java过度使用内存

java过度使用内存,java,jvm,out-of-memory,Java,Jvm,Out Of Memory,在我的一个项目中,我不断压缩小块数据。 现在我发现jvm会增长到6GB的ram(驻留(RES)ram,不是共享或虚拟的,等等),然后由于内存不足而死亡。 这就好像垃圾收集器从未运行过一样。 我已经取出相关代码并粘贴在下面。当我运行它(java6,32位linux)时,它会增长到1GB的ram。 有人知道如何减少内存使用吗 import java.util.Random; import java.util.zip.Deflater; import java.util.zip.Inflater;

在我的一个项目中,我不断压缩小块数据。 现在我发现jvm会增长到6GB的ram(驻留(RES)ram,不是共享或虚拟的,等等),然后由于内存不足而死亡。 这就好像垃圾收集器从未运行过一样。 我已经取出相关代码并粘贴在下面。当我运行它(java6,32位linux)时,它会增长到1GB的ram。 有人知道如何减少内存使用吗

import java.util.Random;
import java.util.zip.Deflater;
import java.util.zip.Inflater;

class test  {
    int blockSize = 4096;
    Random r = new Random();

    public test() throws Exception {
        blockSize = 4096;
        byte [] data = new byte[blockSize];
        for(int index=0; index<blockSize; index++)
            data[index] = (byte)r.nextInt();

        for(long cnt=0; cnt<1000000; cnt++) {
            byte [] result = compress(data);
            if (result != null)
                data[0] = result[0];
        }
    }

    byte [] compress(byte [] in) {
        assert in.length == blockSize;

        Deflater compresser = new Deflater();
        compresser.setInput(in);
        compresser.finish();
        byte [] out = new byte[in.length];
        int outLen = compresser.deflate(out);

        if (outLen < blockSize) {
            byte [] finalOut = new byte[outLen];
            System.arraycopy(out, 0, finalOut, 0, outLen);
            return finalOut;
        }

        return null;
    }

    public static void main(String [] args) throws Exception {
        new test();
    }
}
import java.util.Random;
导入java.util.zip.Deflater;
导入java.util.zip.Inflater;
课堂测试{
int blockSize=4096;
随机r=新随机();
publictest()引发异常{
块大小=4096;
字节[]数据=新字节[块大小];

对于(int index=0;index嗯,在我看来,代码中没有内存泄漏,所以实际上VM似乎没有使用字节数组

“有人知道如何减少内存使用吗?”
好吧,我想试试

byte firstByteOfDataWhichIsCompressedAndThenUncompressed(byte [] in) { ... }
它专门返回未压缩数组的第一个字节,而不是整个数组。我知道,这是一个可怕的方法名,我希望您能找到更好的方法

下面的代码

    for(long cnt=0; cnt<1000000; cnt++) {
        byte [] result = compress(data);
        if (result != null)
            data[0] = result[0];
    }

for(long cnt=0;cnt好吧,Folkert van Heusden解决了他自己的问题,但总而言之:

compress(byte[]in)
-方法的早期,我们创建了一个
java.util.zip.Deflater

我们使用
Deflater
来做一些事情,然后离开
compress()
-方法。我们失去了对
Deflater
-变量的引用。此时,
Deflater
不再使用,并等待垃圾收集器杀死

Deflater
分配Java堆内存和C/C++/本机堆内存。由
Deflater
分配的本机堆内存将一直保留到
Deflater。finalize
-方法由垃圾收集器调用。如果垃圾收集器运行速度不够快(可能有大量可用Java堆内存),我们可能会耗尽C/C++堆内存。如果发生这种情况,我们将得到“内存不足”错误

Oracle bug报告可能与此相关。它包含一段代码片段,说明并再现了此问题:

public class Bug {
    public static void main( String args[] ) {
        while ( true ) {
            /* If ANY of these two lines is not commented, the JVM
             runs out of memory */
            final Deflater deflater = new Deflater( 9, true );
            final Inflater inflater = new Inflater( true );
        }
    }
}

解决方法是在您完成后调用
Deflater.end()
-方法(或
Inflater.end()
)释放资源。

该死,这种情况总是发生:我一直在寻找答案,所以我在某处发布了一个问题。然后突然在5分钟内我自己找到了答案。解决方案是…调用end()压缩数据后在压缩程序上!请将此作为答案发布。通过这种方式,可以对其进行投票,并且此问题的未来访问者将更容易找到它。确实存在泄漏,请参见Folkbert的评论-他错过了结尾()-这很可能是本机内存泄漏,而不是Java内存泄漏,因此不需要GC。
public class Bug {
    public static void main( String args[] ) {
        while ( true ) {
            /* If ANY of these two lines is not commented, the JVM
             runs out of memory */
            final Deflater deflater = new Deflater( 9, true );
            final Inflater inflater = new Inflater( true );
        }
    }
}