文档 for java.lang.Error说:
错误是Throwable的子类,它指示合理的应用程序不应该试图捕捉的严重问题。
但是由于java.lang.Error是java.lang.Throwable的子类,所以我可以捕获这种类型的Throwable。
我明白为什么抓到这种异常不是个好主意。据我所知,如果我们决定捕获它,catch处理程序不应该单独分配任何内存。否则,将再次引发OutOfMemoryError。
所以,我的问题是:
java.lang.OutOfMemoryError时是否有任何真实的场景可能是个好主意?java.lang.OutOfMemoryError,如何确保catch处理程序本身不分配任何内存(任何工具或最佳实践)?发布于 2011-09-09 07:29:57
OOME可以被捕获,但是它通常是无用的,这取决于JVM是否能够在到达catch块时垃圾收集一些对象,以及到那时还剩下多少堆内存。
示例:在我的JVM中,这个程序运行到完成:
import java.util.LinkedList;
import java.util.List;
public class OOMErrorTest {
public static void main(String[] args) {
List<Long> ll = new LinkedList<Long>();
try {
long l = 0;
while(true){
ll.add(new Long(l++));
}
} catch(OutOfMemoryError oome){
System.out.println("Error catched!!");
}
System.out.println("Test finished");
}
}但是,只需在catch块中添加一行就可以向您展示我所指的内容:
import java.util.LinkedList;
import java.util.List;
public class OOMErrorTest {
public static void main(String[] args) {
List<Long> ll = new LinkedList<Long>();
try {
long l = 0;
while(true){
ll.add(new Long(l++));
}
} catch(OutOfMemoryError oome){
System.out.println("Error caught!!");
System.out.println("size:" +ll.size());
}
System.out.println("Test finished");
}
}第一个程序运行良好,因为当到达catch块时,JVM检测到不再使用列表(此检测也可以是编译时进行的优化)。因此,当我们到达print语句时,堆内存几乎完全被释放了,所以我们现在有很大的回旋余地可以继续。这是最好的案子。
但是,如果在捕获OOME之后使用列表ll之类的代码,则JVM无法收集它。这发生在第二个片段中。OOME是由一个新的长创建触发的,但是很快我们就创建了一个新对象( System.out.println行中的一个字符串),堆几乎已经满了,因此抛出了一个新的OOME。这是最坏的情况:我们试图创建一个新对象,失败了,我们捕获了OOME,是的,但是现在需要新堆内存的第一个指令(例如:创建一个新对象)将抛出一个新的OOME。想想看,在这一点上,我们还能做些什么呢?可能只是退出,所以我说没什么用。
JVM不是垃圾收集资源的原因之一是非常可怕的:与其他线程共享的资源也在使用它。Anyonecan看到,如果在任何类型的非实验应用中添加OOME,捕获OOME是多么危险。
我使用的是Windows x86 32位JVM (JRE6)。每个Java应用程序的默认内存为64 is。
https://stackoverflow.com/questions/2679330
复制相似问题