如何优化jvm gc中的大型短期对象

时间:2018-01-19 05:48:05

标签: java memory-leaks garbage-collection jvm

我们遇到了一个关于jvm gc的问题。我们有一个大的QPS应用程序,jvm堆内存增加得非常快。它会在几秒内使用超过2g的堆内存,然后gc触发每次收集超过2g的内存也非常频率.GC收集如下图所示的情况。这有两个问题

  1. gc需要一些时间。更重要的是,它经常发生。
  2. 系统不会稳定。
  3. enter image description here 我像下面的代码一样抽象问题。系统快速分配短期对象。

    public static void fun1() {
        for(int i = 0; i < 5000; i++) {
            Byte[] bs = new Byte[1024 * 1024 * 5];
            bs = null;
        }
    }
    

    所以,我有一些问题:

    1. 很多人说set对象等于null会让gc线程收集容易。那意味着什么?我们都知道,当JVM无法为新对象分配空间时,总会触发次要GC。因此,是否对象为 为null,只有在空间不足时才会触发gc。所以set object为null没有意义。
    2. 如果存在大的短期对象,如何优化这个?我的意思是如何收集这些物品,而不是在年轻一代不够的时候。
    3. 任何建议都会对我有所帮助。

2 个答案:

答案 0 :(得分:0)

我会说你需要缓存它们。而不是每次都尝试重新创建它们来尝试重用已经创建的方法。 尝试使用选项

为您的应用分配更多内存
-Xms8g -Xmx8g

当没有足够的内存时会调用gc,所以如果你有更多的gc不会被频繁调用。

如果没有巨大的物体性质,很难提出有价值的东西。尝试添加此类对象的示例以及如何创建/调用它们。

如果在短期对象中有大字节数组,请尝试将它们放在java之外(例如在文件中并保留文件路径)。

答案 1 :(得分:0)

  

很多人说set对象等于null会让gc线程收集容易

其他几个关于堆栈溢出的问题已经涵盖了这个问题,所以我不会在这里重复这些问题。例如。 Is unused object available for garbage collection when it's still visible in stack?

  

如果存在大的短期对象,如何优化这个?我的意思是如何收集这些物品,而不是在年轻一代不够的时候。

增加年轻一代的规模。这样它就可以包含对象。或者使用G1GC,它可以选择性地收集包含这些对象的区域而不是整个老一代。

您也可以尝试使用direct byte buffers来分配堆外的内存,从而降低GC压力。但是内存将保持分配,直到指向内存的缓冲区被收集。

除此之外,您应该重新设计代码以避免频繁的大量分配。通常可以使用对象池或线程局部变量作为暂存内存。