有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java JVM旧基因不断增加,而eden和survior保持不变

我有一个java spring启动应用程序,它应该运行很长时间,并且还需要响应时间<;全程50毫秒。正常情况下,我们可以为其提供服务,但当老一代的服务接近填满时,CMS就会启动,我们的响应时间SLA就会出现漏洞。我是否可以使用任何策略来确保完全GC永远不会生效

我的服务器是IO密集型的,我们不在内存中存储任何东西,但是有很多并发的IOs(30k rpm),每个IOs响应都携带大约3-4MB的数据。从日志中我观察到,次要GC在一秒钟内运行了近3-4次,由于eden和幸存者空间较小(eden空间为600MB,幸存者空间为75MB),次要GC被频繁触发。由于非常频繁的GC,对象可能会在阈值较小的GC(15)中幸存,并被提升为老gen。因此,我通过制作-XX:NewRatio=1来增加我的年轻gen空间

问题仍然存在,我可以在一秒钟内看到分配失败日志(如下所示)3-4次

[GC (Allocation Failure) 56455.997: [ParNew: 10705358K->222390K(11796480K), 0.0467254 secs] 13148872K->2667031K(24903680K), 0.0468292 secs] [Times: user=0.34 sys=0.00, real=0.05 secs]

我使用new relic监控内存,年轻一代保持不变,而老一代则不断增加,下面是快照

enter image description here

我认为对于我的应用程序来说,一个很好的堆分布策略是年轻一代不断地被填充和清空,而老一代几乎不被使用,因为我们几乎没有任何长寿命的对象。请建议如何实现上述目标,或您可能想到的任何更好的策略


共 (1) 个答案

  1. # 1 楼答案

    建议如下:

    1. 大型OBEJCT(如阵列等)是在旧的gen空间中创建的。因此,检查您正在创建的大型对象以及它们停留的时间

    2. 当对象满足终身阈值时,对象将移动到旧GC。因此,你可以朝这个方向看

    3. 检查您的次要GC和主要GC的执行情况,就好像它们正在快速填充或满足将对象移动到旧代时的阈值一样。

    4. 查看您的伊甸园和幸存者的大小,如果它们太小,则可能触发主要gc并导致对象移动到旧世代。