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

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

  1. 堆内存使用情况
  2. 非堆内存使用情况
  3. 记忆池“CMS Old Gen”
  4. 记忆池“Par Eden Space”
  5. 记忆池“Par Survivor Space”
  6. 内存池“代码缓存”
  7. 内存池“CMS Perm Gen”

这些术语有什么区别。 另请提供一些信息 – 如何通过监视这些参数来查找应用程序行为中的exception。

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

  1. 静态(有几种变化)

你熟悉的堆。

堆栈你也熟悉,但你只是不知道。 如果您有一个带有“本地”变量的方法,那么这些变量将在“调用框架”中分配。 调用方法时会分配“调用框架”,并在从方法返回时删除它,因此使用随着调用而增长的“堆栈”和使用返回收缩的“堆栈”最有效地实现它。

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

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

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

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

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

请点击链接http://www.yourkit.com/docs/kb/sizes.jsp和http://publib.boulder.ibm.com/infocenter/javasdk/v5r0/index.jsp?topic=%2Fcom.ibm .java.doc.diagnostics.50%2Fdiag%2Fproblem_determination%2Faix_mem_heaps.html

非堆也是,JVM具有堆以外的内存,称为非堆内存。 它在JVM启动时创建并存储每类结构,例如运行时常量池,字段和方法数据,以及方法和构造函数的代码,以及实习字符串。

不幸的是,JVM在非堆内存上提供的唯一信息是它的整体大小。 没有关于非堆内存内容的详细信息。

非堆内存大小的exception增长可能表示存在潜在问题,在这种情况下,您可以检查以下内容:

如果存在类加载问题,例如泄漏的加载器。 在这种情况下,可以借助类加载器视图解决问题。 如果有字符串被大量实施。 为了检测这种问题,可以使用对象分配记录。