Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/309.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在java中确定I';我快到OutOfMemoryError了?_Java_Runtime_Out Of Memory_Heap Size - Fatal编程技术网

如何在java中确定I';我快到OutOfMemoryError了?

如何在java中确定I';我快到OutOfMemoryError了?,java,runtime,out-of-memory,heap-size,Java,Runtime,Out Of Memory,Heap Size,我需要找出何时我真的接近OutOfMemoryError,这样我就可以将结果刷新到文件并调用runtime.gc()。我的代码是这样的: Runtime runtime = Runtime.getRuntime(); ... if ((1.0 * runtime.totalMemory() / runtime.maxMemory()) > 0.9) { ... flush results to file ... runtime.gc(); } 有更好的方法吗?谁能帮我一下吗 编辑 我

我需要找出何时我真的接近
OutOfMemoryError
,这样我就可以将结果刷新到文件并调用
runtime.gc()。我的代码是这样的:

Runtime runtime = Runtime.getRuntime();
...
if ((1.0 * runtime.totalMemory() / runtime.maxMemory()) > 0.9) {
... flush results to file ...
  runtime.gc();
}
有更好的方法吗?谁能帮我一下吗

编辑 我明白我是在用这种方式玩火,所以我用了一种更可靠、更简单的方式来判断我什么时候已经受够了。我目前正在使用Jena模型,所以我做了一个简单的检查:如果模型有超过550k条语句,那么我将刷新,这样我就不会有任何风险。

这似乎有效:

public class LowMemoryDetector {

    // Use a soft reference to some memory - will be held onto until GC is nearly out of memory.
    private final SoftReference<byte[]> buffer;
    // The queue that watches for the buffer to be discarded.
    private final ReferenceQueue<byte[]> queue = new ReferenceQueue<>();
    // Have we seen the low condition?
    private boolean seenLow = false;

    public LowMemoryDetector(int bufferSize) {
        // Make my buffer and add register the queue for it to be discarded to.
        buffer = new SoftReference(new byte[bufferSize], queue);
    }

    /**
     * Please be sure to create a new LMD after it returns true.
     * 
     * @return true if a memory low condition has been detected.
     */
    public boolean low () {
        // Preserve that fact that we've seen a low.
        seenLow |= queue.poll() != null;
        return seenLow;
    }
}

private static final int OneMeg = 0x100000;

public void test() {
    LowMemoryDetector lmd = new LowMemoryDetector(2*OneMeg);
    ArrayList<char[]> eatMemory = new ArrayList<>();
    int ate = 0;
    while ( !lmd.low() ) {
        eatMemory.add(new char[OneMeg]);
        ate += 1;
    }
    // Let it go.
    eatMemory = null;
    System.out.println("Ate "+ate);
}
对我来说

使用比您正在使用的最大分配单元大的缓冲区大小。它需要足够大,以便在释放缓冲区时满足任何分配请求


请记住,在64位JVM上,运行时可能会占用大量tb的内存。这种方法在这种情况下几乎肯定会遇到很多困难。

首先:如果您想确定是否接近
OutOfMemoryError
,那么您所要做的就是将当前内存与
JVM
使用的最大内存进行比较,以及您已经做的事情

Second:如果你想将结果刷新到文件中,我想知道为什么你要这样做,只要你接近
OutOfMemoryError
,你只需使用类似
FileWriter
的东西,它有一个缓冲区,因此如果缓冲区被填满,它会自动刷新结果

Third:永远不要显式调用
GC
,这是一种不好的做法,而是优化
JVM
内存参数:

-Xmx -> this param to set the max memory that the JVM can allocate
-Xms -> the init memory that JVM will allocate on the start up
-XX:MaxPermSize= -> this for the max Permanent Generation memory

这些将加速GC


-XX:+UseConMarkSweepGC
为旧空间启用
CMS

如果你想让你的程序在与任何外部因素都不相关的随机时间悲惨而神秘地失败,我强烈建议你将其构建到你的项目中。这太可怕了!你改为修复
OutOfMemoryError
的源代码如何?我想尝试/捕获OutOfMemoryError,然后将所有内容刷新到文件并调用垃圾收集器,但我仍然不想触发错误。我只是想知道什么时候我真的很接近。OOME通常是由于垃圾收集器发现它无法回收足够的空间来满足分配请求而抛出的。如果JVM不能,您打算如何获得更多空间?@Zeeshan我将结果刷新到文件中,取消引用变量并创建新的。我不能使用FileWriter,因为我使用Jena模型写入文件,所以我必须一次写入整个文件。我认为如果我将堆大小增加到1GB就可以了。你可以定期刷新,我不知道如何生成结果,但我相信你可以在内存泄漏之前进行刷新。这就是我试图避免的:如果我知道何时接近OOME,那么我可以刷新并避免它。@Ariel,我想说的是,你根本不需要接近
OutOfMemoryError
,这不是一种健康的方式,你可以依赖其他东西。
-Xmx -> this param to set the max memory that the JVM can allocate
-Xms -> the init memory that JVM will allocate on the start up
-XX:MaxPermSize= -> this for the max Permanent Generation memory
-XX:MaxNewSize=  -> this need to be 40% from your Xmx value
-XX:NewSize= -> this need to be 40% from your Xmx value