电脑桌面
添加蚂蚁七词文库到电脑桌面
安装后可以在桌面快捷访问

性能分析--JVM--应用内存分析

来源:金蝶云社区作者:金蝶2024-09-237

性能分析--JVM--应用内存分析

1 简介

JVM(Java Virtual Machine),即Java虚拟机,是整个Java实现跨平台的最核心部分。

所有的Java程序会首先被编译为.class的类文件,然后在虚拟机上执行,即.class并不直接与机器的操作系统相对应,而是经过虚拟机间接与操作系统交互,由虚拟机将程序解释给本地系统执行。

JVM屏蔽了与具体操作系统平台相关的信息,使得Java程序只需生成在Java虚拟机上运行的目标代码(字节码),即可在多种平台上不加修改地运行。因此,JVM的性能优化对苍穹性能影响至关重要。

小编本期总结了苍穹性能分析实战过程中的一些经验,为大家讲讲和内存相关的性能分析方法。


2 苍穹应用Java内存分析

2.1 JVM基本结构

在进行内存分析前,我们需先了解JVM的内存结构。具体结构如下图所示:



JVM 运行时的数据区主要包括:堆、栈、方法区、程序计数器等。而 JVM 的优化问题主要在于线程共享的数据区:堆、方法区。其中最核心的堆空间结构如下:



如上图所示,Java堆的内存划分为Eden(年轻代)、Old Memory(老年代)、Perm(永久代)。在Jdk1.8中,永久代被移除,使用元数据MetaSpace代替。


 Eden(年轻代)

1. 年轻代分为较大的Eden空间和两份较小的SurvivorFrom、Survivor To空间,比例默认为8:1:1;

2. 年轻代使用复制清除算法(Copinng算法),原因是年轻代每次GC(Garbage Collection,垃圾回收)都要回收大部分对象。每次GC时只使用Eden和其中一块Survivor空间,然后把存活对象放到未使用的Survivor空间中,清空Eden和刚才使用过的Survivor空间;

3. 内存不足时发生Minor GC。


 Old Memory(老年代)

采用标记-整理算法(mark-compact算法),原因是老年代每次GC只会回收少部分对象。


 Perm(永久代)

永久代用于存储类的元数据,也就是方法区。

1. Perm的废除:在jdk1.8中,Perm被替换成MetaSpace,MetaSpace存放在本地内存中。原因是永久代进程内存不够用,或者发生内存泄漏;

2. MetaSpace(元空间):元空间的本质和永久代类似,都是对JVM规范中方法区的实现。不过元空间与永久代之间最大的区别在于:元空间并不在虚拟机中,而是使用本地内存

2.2 JVM内存使用分析

我们可以借助苍穹的monitor平台和Java的原生命令来查看JVM内存使用情况。在monitor平台中的指标监控如下:



这里主要关注堆内存、Metaspace、GC-Duration三个指标。


 堆内存

堆内存是JVM中最大的内存。如果堆内存使用量一直接近max值,说明内存不足或者有内存泄漏,不能通过GC释放内存空间。如果堆内存长时间得不到释放就容易发生堆内存的OOM(Out Of Memory,内存溢出)。


 Metaspace

Metaspace元数据区主要是存放类信息和常量信息。和堆内存一样,也会有GC操作来释放内存。如果释放不了也会发生元数据的OOM。


 GC-Duration

GC-Duration指标图的横坐标表示时间,纵坐标表示GC使用的时间,下面的标注表示最近一次YongGC和FullGC所花的时间。曲线图出现一次折线表示发生了一次GC操作。我们需重点关注FullGC的次数和时间。


查看堆内存和非堆内存的另一种办法为:

添加JVM选项-XX:NativeMemoryTracking=summary|detail,然后执行命令jcmd <pid> VM.native_memory scale=MB。



如上图所示,上方红框表示堆内存,其中:

  • “reserved”表示应用可用的内存大小;

  • “committed”表示应用正在使用的内存大小;

  • “Java Heap” 部分表示对内存的使用情况;

  • “committed=4096MB”表示预分配了全部堆内存。如果要看实际使用了多少内存,可以使用“jmap–heap pid”命令查看。


下方红框则表示Java的非堆内存,其中:

  • “Class”部分表示已经加载的classes个数,占用121M,对应元数据空间 MetaData;

  • “Thread”部分表示目前有401个线程,占用了404MB,默认1个线程1M;

  • “Code”部分表示JIT生成的或者缓存的instructions占用了95MB;

  • “GC”部分表示目前已经占用了95MB的内存空间用于帮助GC;

  • “Compiler”部分表示compiler生成code的时候占用的内存;

  • “Internal”部分表示命令行解析、JVMTI等占用了51MB,对应直接内存;

  • “Symbol”部分表示诸如string table及constant pool等symbol占用了25MB;

  • “Native Memory Tracking”部分表示该功能自身占用了6M;

  • “Unknow”部分表示其他未知使用内存。


通过分析堆内存和非堆内存占用,我们可以合理地设置堆大小和容器大小。


需要2G heap,运行环境为jdk 1.8为例,通过“堆内存 + 线程数*线程栈 + 元空间 + 其他堆外内存”来估算容器大小,即2G+1000*1M+256M+(~2G)=~3.5G(~5.5G)


注:堆外内存=线程数*线程栈+元空间+其他堆外内存


一般情况下,苍穹容器内存规格=JVM堆内存+2G,但对于一些大型项目,如果我们通过分析非堆内存的占用,并根据实际情况调整容器内存规格,苍穹容器内存规格=JVM堆内存+4G也是正常的。


3 Full GC 和OOM

在JVM运行中会产生很多不可达对象,这些对象被称为垃圾对象。JVM需要不断地回收这些垃圾对象以腾出空闲内存。


对年轻代(包括 Eden 和 Survivor 区域)进行GC被称为 Minor GC,对老年代进行GC称为Major GC,而Full GC是对整个堆而言,在最近几个版本的JDK里默认包括了对永久代,即方法区的回收(JDK8中无永久代了)。


出现Full GC的时候经常伴随至少一次的Minor GC,但非绝对。Major GC的速度一般会比Minor GC慢10倍以上,所以我们需重点关注Full GC。一般而言,分析Full GC流程如下。

3.1 查看Full GC日志

配置JVM参数打开GC日志:

-Xloggc:/mservice/logs/gc_%t.log 
-XX:+PrintGCDetails
-XX:+PrintGCDateStamps 
-XX:+PrintGCApplicationStoppedTime


默认情况下jdk1.8是使用UseParallelGC垃圾收集器:

/jdk/bin/java -XX:+PrintCommandLineFlags -version
-XX:InitialHeapSize=2147483648 
-XX:MaxHeapSize=32210157568 
-XX:+PrintCommandLineFlags 
-XX:+UseCompressedClassPointers 
-XX:+UseCompressedOops 
-XX:+UseParallelGC


苍穹标准是使用G1垃圾收集器,JVM参数设置如下:

-XX:+UseG1GC 
-XX:G1HeapRegionSize=8m 
-XX:G1ReservePercent=5


查看Full GC日志:

grep -i "full" gc.log



上图发生了6次Full GC,每次GC的时间在16s以上,表示应用程序在这16s中是暂停状态,这对程序的影响是不可忽视的。


Full GC 的3种情况:

1. 偶尔出现Full GC且GC后能够回收大量空间,Full GC时间1-2s说明速度很快,Full GC效果很好,属于正常现象;

2. 出现大量Full GC,会导致Java进程CPU使用率很高,系统很卡顿;

3. 出现大量Full GC出现且GC时间长,回收空间很小,则可能会导致OOM,系统中断。

3.2 分析Full GC日志

可以直接查看GC日志文件进行分析,如下图所示:



"Full GC(Allocation Failure)"表示Full GC失败;Full GC之前堆占用的空间3018.5M,Full GC之后还是3018.5M,表示GC效果不好,没有释放出空闲空间。


为进一步统计暂停时间,可执行以下命令:

grep -i secs gc.log | awk -F '),' '{print $2}' | grep -v "^$" | sort -r | more


该命令可以得到暂停时间的倒序排序:

grep -i "which application" gc.log | awk -F "stopped:" '{print $2}' 

性能分析--JVM--应用内存分析

1 简介JVM(Java Virtual Machine),即Java虚拟机,是整个Java实现跨平台的最核心部分。所有的Java程序会首先被编译为.class的类文件,...
点击下载文档文档为doc格式

声明:除非特别标注,否则均为本站原创文章,转载时请以链接形式注明文章出处。如若本站内容侵犯了原著者的合法权益,可联系本站删除。

确认删除?
回到顶部
客服QQ
  • 客服QQ点击这里给我发消息
QQ群
  • 答案:my7c点击这里加入QQ群
支持邮箱
微信
  • 微信