Java 非堆内存和堆栈内存之间有什么区别?它们是否相同,如果不是它们之间的区别是什么?

我正在使用Jconsole来监视Java应用程序。内存选项卡显示不同的堆和非堆内存,如

  1. 堆内存使用情况
  2. 非堆内存使用情况
  3. 内存池“CMS 老一代”
  4. 记忆池“帕伊甸园空间”
  5. 记忆池“幸存者空间”
  6. 内存池“代码缓存”
  7. 記憶體池“CMS Perm Gen”

这些术语之间有什么区别。另外,请提供一些有关的信息 - 如何通过监视这些参数来查找应用程序行为中的异常。


答案 1

在所有基于 C 的语言(以及大多数其他语言)中,基本上有三类存储:

  1. 静态(具有多种变体)

您熟悉的堆。

堆栈你也很熟悉,但你只是不知道它。当您有一个包含“局部”变量的方法时,这些变量将在“调用框架”中分配。“调用帧”在调用方法时分配,在从方法返回时删除,因此,使用随调用而增长并随返回收缩的“堆栈”最有效地实现它。

静态是你没有显式分配的东西,基本上从程序执行开始就存在。

堆栈所需的空间通常相当小,并且在上述类别中与“非堆内存”混为一谈。


答案 2

非堆内存是 JVM 为堆以外的目的分配的所有内存。这包括:

  • 调用堆栈(如您所指出的);
  • 由本机代码分配的内存(例如,用于堆外缓存);
  • 在HotSpot 8中,元空间(永久一代的替代品);
  • JIT 编译器使用的内存(编译的本机代码)。

在您的列表中,“CMS Old Gen”,“Par Eden Space”,“Par Survivor Space”和“CMS Perm Gen”都是指堆的各个部分。


推荐