我正在使用Jconsole监视Java应用程序。内存选项卡显示不同的堆和非堆内存,如
- 堆内存使用情况
- 非堆内存使用情况
- 内存池"CMS旧一代"
- 记忆池"Par Eden Space"
- 内存池"Par幸存者空间"
- 内存池"代码缓存"
- 内存池"CMS Perm Gen"
这些术语之间有什么区别。此外,请提供一些关于如何通过监控这些参数来发现应用程序行为异常的信息。
在所有基于C的语言(以及大多数其他语言)中,基本上有三类存储:
- 堆
- 堆栈
- 静态(有几种变化)
堆你很熟悉。
你也熟悉Stack,但你只是不知道。当你有一个带有"局部"变量的方法时,这些变量会在"调用框架"中分配。"调用框架"在调用方法时分配,在从方法返回时删除,因此使用随调用而增长、随返回而收缩的"堆栈"可以最有效地实现。
静态是您没有显式分配的东西,从程序执行开始就基本上存在。
堆栈所需的空间通常相当小,并与上述类别中的"非堆内存"集中在一起。
非堆内存是JVM为堆以外的目的分配的所有内存。这包括:
- 调用堆栈(如您所述)
- 由本机代码分配的内存(例如,用于堆外缓存)
- 在HotSpot 8中,元空间(永久一代的替代品)
- JIT编译器使用的内存(编译的本机代码)
在您的列表中,"CMS Old Gen"、"Par Eden Space"、"Pars Survivor Space"one_answers"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在非堆内存上提供的唯一信息是它的总体大小。没有关于非堆内存内容的详细信息。
非堆内存大小的异常增长可能表明存在潜在问题,在这种情况下,您可以检查以下内容:
如果存在类加载问题,例如加载程序泄漏。在这种情况下,可以借助类加载器视图来解决问题。如果有字符串被大量扣留。为了检测这样的问题,可以使用对象分配记录。