Ank*_*kit 4 java garbage-collection jvm
我们有一个部署在tomcat 8应用服务器上的应用程序,当前监控服务器(zabbix)配置为在堆内存利用率为90%时生成警报.
生成了某些警报,促使我们进行堆转储分析.堆转储没有真正发生,没有内存泄漏.由于没有GC,有很多无法到达的对象没有被清理干净.
JVM配置:
-Xms8192m -Xmx8192m -XX:PermSize=128M -XX:MaxPermSize=256m
-XX:+UseParallelGC -XX:NewRatio=3 -XX:+PrintGCDetails
-XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/app/apache-tomcat-8.0.33
-XX:ParallelGCThreads=2
-Xloggc:/app/apache-tomcat-8.0.33/logs/gc.log
-verbose:gc -XX:+PrintGCDetails -XX:+PrintGCDateStamps
-XX:+PrintGCTimeStamps -XX:GCLogFileSize=50m -XX:+UseGCLogFileRotation -XX:NumberOfGCLogFiles=30
Run Code Online (Sandbox Code Playgroud)
我们尝试使用jcmd命令手动运行垃圾收集,它清理了内存.运行jcmd后的GC日志:
2016-11-04T03:06:31.751-0400: 1974627.198: [Full GC (System.gc()) [PSYoungGen: 18528K->0K(2049024K)] [ParOldGen: 5750601K->25745K(6291456K)] 5769129K->25745K(8340480K), [Metaspace: 21786K->21592K(1069056K)], 0.1337369 secs] [Times: user=0.19 sys=0.00, real=0.14 secs]
Run Code Online (Sandbox Code Playgroud)
问题:
垃圾收集器决定收集每个垃圾收集器不同.我的(并行GC)垃圾收集器运行时,我找不到任何硬性约定.许多垃圾收集器还会调整几个不同的变量,这些变量会影响它何时运行.
正如您已经注意到的那样,您的应用程序可能具有较高的堆使用率并且仍可正常运 您在应用程序中寻找的是垃圾收集器仍然有效.这意味着它可以在一次运行中清理大量垃圾.
大多数垃圾收集器有两个或更多策略,一个用于"年轻"对象,一个用于"旧"对象.当一个年轻的物体没有被收集在最新的(几个)收集中时,它就变成了一个旧物体.这背后的想法是,如果一个对象没有被收集,它可能也不会在下次收集.(大多数物体要么活得很短,要么很长).垃圾收集器对年轻物体进行了非常有效但不完美的清洁.当它没有释放足够的数据时,就会对所有(年轻的旧)对象进行更昂贵的垃圾收集.
这通常会产生锯齿(取自本网站):
在这里,您可以看到堆大小的许多小滴和缓慢增长的堆.每隔一段时间就会完成一个大型集合,并且有很大的下降.实际"使用"的内存是大量收集后剩余的内存量.
在确定应用程序的运行状况时,这会导致以下几个方面:
在大多数情况下,您需要监控负载下应用程序的行为,以查看适合您的值.
并行垃圾收集器使用类似的条件来确定是否所有仍然良好:
如果在垃圾收集中花费的总时间超过98%并且恢复的堆少于2%,则抛出OutOfMemoryError.
使用VisualVM和Jconsole可以很好地看到所有这些统计信息.我不确定您可以在监控工具中使用哪个触发器
| 归档时间: |
|
| 查看次数: |
4254 次 |
| 最近记录: |