当多个线程调用相同的函数时,Java/C#如何分配内存

Posted

技术标签:

【中文标题】当多个线程调用相同的函数时,Java/C#如何分配内存【英文标题】:How does Java/C# allocate memory when multiple threads call same functions 【发布时间】:2013-03-03 16:52:52 【问题描述】:

假设下面的代码:

Class test

   void foo()
   
      int i=0;
   


Test t=new Test();
// if many threads call t.foo();

每个线程都有自己的内存来调用 foo 吗?这意味着每个线程都有自己的i

Java/C# 在调用函数时如何分配内存? 我记得,在 C# 中,每个线程将分配 1M 内存。 Java 呢?

【问题讨论】:

供以后参考,Java没有函数,它有方法 我猜你想到了来自 C 的 fork/join? Sooo...线程?笏?每个线程都有自己的堆栈,其中包含所有局部变量。类似的东西。 【参考方案1】:

单线程和多线程应用程序之间的内存分配基本上没有区别(至少在 .Net/Windows 世界中)。

在堆(普通对象)或堆栈(用于局部变量/局部结构/函数参数)中分配的内存。 C# 应用程序(和大多数 Windows 应用程序)的默认堆栈大小是每个线程 1Mb,但堆在所有线程之间共享。

【讨论】:

【参考方案2】:

在您为 C# 描述的场景中会发生什么(不确定 Java,但我相信它的行为会相似)是值 i 将存储在短期存储中(堆栈或寄存器取决于 JIT 想要什么去做)。这是因为它是一个值类型。如果它是一个引用类型,那么它很可能会在堆上。

每次调用函数时(不管线程如何),函数都会获得变量 i 的一个新实例。因此,哪个线程或多少个线程无关紧要,只需要对函数进行多少次调用。

需要注意的一点是,您不能总是保证某些东西会被分配到哪里,而且在大多数情况下您不应该关心。只要不影响事件的单线程视图和程序的功能,JIT/CLR 就可以做它想做的任何事情(存在边缘情况,但对于 99% 的代码,此语句是正确的)。

您还可以阅读 Eric Lippert 对此问题的回答 (Fields of class, are they stored in the stack or heap?) 以获得更好的理解,以及他的博客 (http://blogs.msdn.com/b/ericlippert/) 和 (http://ericlippert.com/) 他已经多次详细讨论了这个问题。

【讨论】:

以上是关于当多个线程调用相同的函数时,Java/C#如何分配内存的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 std::thread C++ 生成多个调用相同函数的线程 [关闭]

如何选择线程的优先级?

java类内多个函数如何同步

[转]如何写出线程安全的类和函数

线程同步

多个线程使用不同的参数值集调用相同的函数