java过度使用内存 [英] excessive memory use by java

查看:168
本文介绍了java过度使用内存的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在我的一个项目中,我经常压缩很少的数据块。
现在我发现jvm然后增长到6GB ram(驻留(RES)RAM,不共享或虚拟等)然后因为内存不足而死亡。
好​​像垃圾收集器从未运行过。
我已经拿出相关代码并粘贴在下面。当我运行它(java6,32位linux)时,它增长到1GB内存。
任何人都知道如何减少内存使用量?

In a project of mine I constantly compress little blocks of data. Now I find out that the jvm then grows to 6GB of ram (resident (RES) RAM, not shared or virtual or so) and then die because of out of memory. It is as if the garbage collector never runs or so. I've pulled out the relevant code and pasted it below. When I run it (java6, 32 bit linux) it grows to 1GB of ram. Anyone got an idea how to reduce the memory usage?

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();
    }
}


推荐答案

好,Folkert van Heusden解决了他自己的问题,但总结一下:

Well, Folkert van Heusden solved his own problem, but to summarize:

早期的压缩(byte [] in) -method,我们创建一个 java.util.zip.Deflater

Early in the compress(byte [] in)-method, we create a java.util.zip.Deflater.

我们使用 Deflater 做一些事情,然后我们离开 compress() -method。我们放弃了对 deflater -variable的引用。此时, Deflater 已不再使用,正在等待被垃圾收集器杀死。

We use the Deflater to do some stuff, and then we leave the compress()-method. We loose our reference to the deflater-variable. At this point, the Deflater is no longer in use, and is waiting to be killed by the garbage collector.

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

Deflater allocates both Java heap memory and C/C++/native heap memory. The native heap memory that are allocated by a Deflater, will be held until Deflater.finalize-method is called by the garbage collector. If the garbage collector doesn't run fast enough (there might be plenty free java heap memory), we can run out of C/C++ heap memory. If this happen, we will get "Out of memory"-errors.

Oracle错误报告 JDK-4797189 可能与此有关。它包含一个代码片段,用于说明和重现问题:

The Oracle bug report JDK-4797189 is probably related. It contains a code snippet that illustrates and reproduces the problem:

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() -method(或 Inflater.end())完成资源。

The solution is to free the resources when you are finished by calling the Deflater.end()-method (or Inflater.end()).

这篇关于java过度使用内存的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆