所以今天在学习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,直到找到另一个错误为止(依此类推......直到找到上限)
由于我在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");
}
}
你有没有尝试编译它?
当然,它不起作用
我正在尝试执行以下操作:
通过我自己的手动测试,我发现了它的价值 的 92274686 即可。这是神奇的数字。我不知道为什么会这样,以及它是否只是我自己的计算机的价值。这将是 如果有人可以发布可以吐出这个的修改过的代码,真棒 结果
答案 0 :(得分:3)
您抓住Exception
,但OutOfMemoryError
是Error
。请注意,Error
和Exception
是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 solution中one 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)
。 ,我之前忽略了它。
它似乎对我来说很完美,现在我找到了神奇的数字。我欢迎所有可能表明这个答案错误的评论,为什么? :)