从java.lang.OutOfMemoryError

时间:2016-08-29 14:06:31

标签: java out-of-memory

所以今天在学习Java时,我终于遇到了这个特殊的错误。似乎这个错误非常普遍,并试图从中恢复已经获得了混合反应。有些人认为it is useful in certain scenarios是一个很好的'知道',some have used it in their projects,而其他人vehemently oppose the idea会抓住这个错误,然后是很多others are just as confused as me

编辑:哦顺便说一句,这是我遇到的错误。我希望捕获这些错误并将增量值减少1/10,直到找到另一个错误为止(依此类推......直到找到上限) This is the error I've encountered

由于我在Java中采取了我的步骤,并且在这个主题上找不到任何具体的内容,我想就这个特定的例子请求你的帮助:

public class SpeedDemoClass {
        static int iterations=0;
        static int incrementor=10000000;
    public static void main(String[] args) {
        while(incrementor>1){
            try{
              iterations=iterations+incrementor;
              iterator(iterations);
            }
            catch(Exception e){
                System.out.println("So this is the limiting error: "+e);
                iterations=iterations-incrementor;
                incrementor=incrementor/10;
                iterations=iterations+incrementor;
            }
        }
        System.out.println("The upper limit of iterations is: "+iterations);
    }

    public static void iterator(int a){
            long start_time= System.currentTimeMillis();
            StringBuilder sbuild= new StringBuilder("JAVA");
            for(int i=0;i<a;i++){
                sbuild.append("JAVA");
            }
            System.out.println("Performing "+a+" append operations;"
                    +"process completed in :"
                    +(System.currentTimeMillis()-start_time)+"ms");
    }
}

你有没有尝试编译它?

  

当然,它不起作用

以下是我正在尝试做的简短说明!

我正在尝试执行以下操作:

  1. 初始化 incrementor = 10000000和迭代 = 0并将 incrementor = incrementor + iterations的结果传递给 iterator()< /强>
  2. 如果出现错误,程序应该捕获它,然后通过** incrementor 减少迭代*,然后将 incrementor 除以10,然后再次尝试
  3. 重复步骤1到2,直到它开始工作。
  4. 目标是找到迭代的值,它会产生错误并在每次迭代后保持低于该级别,直到找到迭代的值的上限
    (即 incrementor 变为0时)
  5.   

    通过我自己的手动测试,我发现了它的价值   的 92274686 即可。这是神奇的数字。我不知道为什么会这样,以及它是否只是我自己的计算机的价值。这将是   如果有人可以发布可以吐出这个的修改过的代码,真棒   结果

5 个答案:

答案 0 :(得分:3)

您抓住Exception,但OutOfMemoryErrorError。请注意,ErrorException是Java中的两个不同类!但是,两者都实现Throwable

catch子句限制要捕获的Throwable类的类型。由于Error不是Exception,因此您的代码无法抓住OutOfMemoryError

答案 1 :(得分:3)

那个&#34;幻数&#34;如果你分配一些耗尽内存的额外对象,使用内存较少的PC等,或者分配内存智能,将会改变。 试图估计内存消耗暴力是一个坏主意!

相反,要了解Java内存分配的工作原理,字符串生成器的内存布局以及如何控制它。在这里,您应该研究方法ensureCapacityInternal

查看你得到的错误 - 特别是类和行号。

我敢打赌,如果你更换这一行:

StringBuilder sbuild= new StringBuilder("JAVA");

通过

StringBuilder sbuild= new StringBuilder(500000000);

然后在看到OOM错误之前你会得到更多。捕获此错误不是一个非常聪明的方法。观察内存消耗有一些不错的变种;但是只有了解了Java的记忆组织后才真正使用它们,所以你不能得出错误的结论。

你的电脑可能有8 GB的内存?尝试使用java -Xmx7500m。到目前为止你可能会达到3倍。因为默认情况下,Java只使用25%的内存,只是为了让其他进程也使用一些内存。如果你想让Java使用你所有的内存,你必须告诉它这是你想要的。

答案 2 :(得分:2)

以捕捉outofmemoryerror只是用OutOfMemoryError替换catch中的Exception

catch(OutOfMemoryError e)

答案 3 :(得分:1)

内存不足通常意味着你无法做其他事情,虚拟机已经崩溃了。虽然看起来你可以做一些事情,比如解除分配内存,但Java会为你做所有的内存管理。你不能解除分配任何东西,你可以取消引用对象然后触发垃圾收集,但是在异常发生的那一刻它已经太晚了。你几乎可以做任何事情,需要内存分配,而你没有。

通常,无法恢复VM引发的所有错误。通常因为VM本身不稳定,并且您无法访问VM的内部以修复它。不仅如此,但您的软件可以解决它的情况很少见。

答案 4 :(得分:1)

我打算发布此解决方案,但somebody beat me to it。今天早些时候,我似乎忽略了a solutionone of the alternative questions of this sort中提到的this question the original code

嗯,只是为了一般的礼貌,以便将来的人不要忽视像我一样的面对面的解决方案,我发布的答案就像他们来的一样简单*。以下是我所做的一些修改,使其成为现实。看来,有可能捕获java.lang.OutOfMemoryError,虽然我还不知道我真正做过的事情的含义。

* 请随时纠正我并阅读本答复的结尾:)

  

我将来会更新这个答案,反映我后来可能发现的事情(像差异等

所以,不用多说了,这是原始荣耀中的代码:

public class SpeedDemoClass {
    static int iterations=0;
    static int incrementor=10000000;
    public static void main(String[] args) {
        while(incrementor>0){
            try{
                iterations=iterations+incrementor;
                int a = iterations;
                long start_time= System.currentTimeMillis();
                StringBuilder sbuild= new StringBuilder("JAVA");
                for(int i=0;i<a;i++){
                    sbuild.append("JAVA");
                }
                System.out.println("Performing "+a+" append operations;"
                    +"process completed in :"
                    +(System.currentTimeMillis()-start_time)+"ms");
            }
            catch(OutOfMemoryError e){
                System.out.println("OutOfMemory bound reached beyond this point with error: "+e
                +"\nReverting back, and Changing the value of incrementor by 1/10th...");
                iterations=iterations-incrementor;
                incrementor=incrementor/10;
                iterations=iterations+incrementor;
            }
        }
        System.out.println("The upper limit of iterations is: "+iterations);
    }
}
  

<强>更新日志:   
如果还不明显,我对Turns out there is a native solution available做了一些微小的改动。   
(1)我抛弃了方法iterator(),因为我现在意识到这让人们更难意识到问题的意图。   
(2)我将catch(Exception e)更改为catch(OutOfMemoryError e)Output-Part-1,我之前忽略了它。

输出:

Output-Part-2 fiddle

它似乎对我来说很完美,现在我找到了神奇的数字。我欢迎所有可能表明这个答案错误的评论,为什么? :)