这个问题在这里已经有答案了:
如何处理“java.lang.outofmemoryerror:java heap space”错误(21个答案)
4个月前关门了。
我的应用程序的垃圾收集器有问题,我在gcp环境中使用kubernetes和bigtable作为数据源。
当接收到负载时,应用程序不会释放内存空间,直到k8s重新启动pod。我使用探查器来查看jvm的行为,这就是结果。
在“old gen”池中,可以看到内存已满,但它从不释放空间,直到重新启动并重新启动,内存才会被填满。
在“伊甸园空间”的池子里可以看到,当它被填满的时候,空间被释放了,永远不会达到极限。
这是在k8s中创建docker映像以部署它时的jvm配置。
java
-XX:+UnlockExperimentalVMOptions
-XX:+UseG1GC
-XX:+UseCGroupMemoryLimitForHeap
-XX:+AlwaysPreTouch
-XX:ParallelGCThreads=5
-XX:GCTimeRatio=4
-XX:MaxGCPauseMillis=100
-XX:MinHeapFreeRatio=30
-XX:MaxHeapFreeRatio=30
-Xms512m
-Xmx4608m
同样的配置也应用在另一个进行rest调用的应用程序中,并且从未出现过这种情况下的内存填充问题。
java版本是1.8
感谢你的帮助。
格雷廷斯。
1条答案
按热度按时间ego6inou1#
首先,你必须找出你的问题的根本原因才能继续。我建议您使用-xx:+printgcdetails和-xx:+printgctimestamps收集更多关于该主题的信息。如果你关于“老根”池永远不会释放空间的假设是正确的(老实说,这从图片上看并不明显),你可以应用一些技巧来处理它:
通过-xx:maxnewsize、-xx:newsize、-xx:maxoldsize、-xx:maxoldsize、-xx:maxoldsize直接指定新的和旧的gc大小,以确保有足够的空间用于旧的生成
通过-xx:+printgcdetails和-xx:+printgctimestamps收集更多日志,查看是否有任何问题是由于过度使用某一代而导致的
尝试通过-xx:survivorratio增加幸存者空间比率,以加速旧一代对象的收集