TIPS:按小写字母q可以退出top命令
JVM进程的RES列的值和JVM的heap(堆)的关系也很有意思,RES列的值代表JVM进程在运行过程中曾经使用过的最大内存, 注意是曾经使用过的最大内存 ,并不代表此时此刻JVM堆使用的内存大小。举个例子,假如JVM在业务高峰期有大量请求进来,此时堆内存使用量肯定会上升,假如此时堆内存的使用量为5G,然后触发了JVM的垃圾回收,垃圾回收之后JVM堆内存使用量下降到了1G,此时你用top命令去看这个JVM进程的RES列的值有很大可能还是5G,原因就是这5G内存目前还归属JVM进程管理并使用,JVM 可能不会立即 把回收掉的堆空间还给操作系统。
只要RES列的值不大于我们给JVM设置Xmx的值,就没有关系。Xmx这个参数的意思就是告诉操作系统,JVM本大爷我有可能要使用Xmx这么大的内存,你操作系统提前做好心理准备。JVM进程刚运行的时候并不会直接找操作系统要Xmx这么大的内存,JVM在运行的过程中根据自己的情况一点一点问操作系统申请的。一旦JVM进程从操作系统申请到内存之后,JVM在运行的过程中就可能就不会还给操作系统了。因为JVM跟操作系统之间如果总是借呀还呀的就会很浪费性能,没有什么必要。JVM进程退出之后占用的这些内存肯定会释放给操作系统的。关于JVM是否把空闲的堆(heap)内存还给操作系统这件事,JVM提供了一些参数:
-XX:MinHeapFreeRatio、
-XX:MaxHeapFreeRatio、
-XX:-ShrinkHeapInSteps
这几个参数你们自己查资料吧。
怎么验证这个说法?先找一个运行了1天以上的JVM进程,然后使用top命令看下这个JVM进程的RES列的值,然后再用我后面介绍的jmap -heap 19463 命令看一下JVM进程堆的使用情况就知道了。
这块知识点摘自掘金APP上面 空无 大神的文章《 运维:你们 JAVA 服务内存占用太高,还只增不减!告警了,快来接锅 》。
熊峰 大神的文章《 JVM调优之探索CMS和G1的物理内存归还机制 》。
stackoverflow 网站的提问《 Does GC release back memory to OS? 》。
Oracle官方文档《 Default Option Values for Heap Size 》。
3 JAVA自带命令–jstat,查看GC(垃圾回收情况)jstat这个命令在JDK的安装目录bin/下面
3.1 使用 jstat 查看 GC(垃圾回收) 的情况jstat -gc jvm进程PID 2000
这个命令会每隔2秒统计一下JVM进程(PID):19463的垃圾收集情况,命令最后2000的意思就是每隔2秒统计一次。使用jstat命令可以实时监测到YGC和FGC的情况,包括每次YGC和FGC各花费了多长时间,到目前为止总共进行了多少次YGC和FGC。
jstat -gcutil jvm进程PID 2000
这个命令里面的-gcutil 监视内容与-gc基本相同,但输出主要关注已使用空间占总空间的百分比 。
也可以写成 jstat -gcutil jvm进程PID 2s , 2s也是2秒钟刷新一次的意思。还有一种写法是 jstat -gcutil 19463 2s 5 ,这个命令是2秒钟刷新一次,总共统计5次就行了,5次之后自动结束jstat命令,不需要你手工按crtl c去终止命令。