JVM的实际内存分配以及它们有何不同?

时间:2011-11-03 19:15:41

标签: java memory jvm

这可能看起来很多问题,但它们都是相互关联的。我很困惑,因为分配的堆空间在哪里以及堆栈内存位于何处?
如果两者都存在于主存储器中那么为什么说堆栈存储器更容易访问?为什么我们不能在堆栈存储器中分配对象?
由于类存储在PermGen中,在这里分配了这个空间,它与堆空间有什么不同以及存储常量字符串的位置?

2 个答案:

答案 0 :(得分:4)

  1. “堆和堆栈在哪里分配?” accepted answer to this question covers this.每个线程都有自己的堆栈,它们共享一个堆。操作系统控制堆栈和堆项的确切内存位置,并且它会有所不同。
  2. “为什么堆栈内存更容易访问”每个线程都有自己的堆栈,因此并发问题较少。堆栈和堆都有资格在L1, L2, and L3 portions of the memory hierarchy中进行缓存,所以我不同意Daniel的回答。真的,我不会说一种内存比另一种更容易访问。
  3. “为什么我们不能在堆栈内存中分配对象?”这是JVM采取的设计决策。在其他语言(如C / C ++)中,您可以在堆栈上分配对象。从分配了stack frame这样的对象丢失的函数返回后。 C / C ++程序中常见的错误来源是共享指向这种堆栈分配对象的指针。我敢打赌,这就是为什么JVM设计师做出这个选择,虽然我不确定。
  4. PermGen是堆的另一部分。在JVM的生命周期中,常量字符串存储在此处。它is garbage collected just like the rest of the heap.

答案 1 :(得分:2)

  

如果两者都存在于主存储器中,那么为什么说堆栈存储器更容易访问

访问速度和分配速度。堆栈分配(如在alloca中)很快,因为不需要搜索未使用的内存块。但是Java不允许堆栈分配,除非你计算新堆栈帧的分配。

访问堆栈内存很快,因为它往往会被缓存。不仅当地人彼此靠近,他们也非常紧凑地存放。

  

为什么我们不能在堆栈内存中分配对象?

这很有用,但很危险。用户可以在堆栈上分配一个对象,从永久对象创建对它的引用,然后在关联的堆栈帧消失后尝试访问该对象。

原语存储在堆栈上是安全的,因为我们无法从其他地方创建对它们的引用。

  

由于类存储在PermGen中,分配了这个空间,它与堆空间有什么不同,存储常量字符串的位置是什么?

PermGen只是另一个堆空间。字符串文字存储在文字池中,文字池只是内存中的一个表,在加载类时会分配。