Lea*_*ner 5 java out-of-memory
我需要你们专家的一些了解
本程序不会阻止阻塞(因为Heap已满,但我想了解原因)
public class OOME_NotCatch {
static List l = new ArrayList();
static Long i = new Long(1);
public static void main(String[] args) {
try {
while (true) {
l.add(i);
i++;
}
} catch (OutOfMemoryError e) {
e.printStackTrace();
System.out.println("Encountered OutOfMemoryError");
}
}
}
//Console : Exception in thread "main"
Run Code Online (Sandbox Code Playgroud)
但即使在获得OOME之后,下面的程序运行良好:
public class Catch_OOME_Collection {
static List l = new ArrayList();
public static void main(String[] args) {
try {
while (true) {
l.add(new byte[1000000]);
System.out.println("size " + l.size());
}
} catch (OutOfMemoryError e) {
System.out.println("Encountered OutOfMemoryError");
e.printStackTrace();
System.out.println("size of list is " + l.size());
Iterator i = l.iterator();
while(i.hasNext()){
System.out.println(i.next().toString());
i.remove();
}
while (true) {
System.out.println("keep printing");
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
在看到同样错误OOME的不同结果后,我有点困惑.请指导
我的理解是,在第一个程序中,在尝试分配一个只占用几个字节内存的新Long对象时会抛出OOME.这意味着堆已完全填满,并且不再有可用的内存来运行catch块.
在第二个程序中,在尝试分配一个100万字节的新数组时抛出OOME.它失败了,但这可能意味着堆仍然有999,990字节可用,这足以让catch块执行.
两个程序都进入catch块.发生的事情是,在它设法生成并打印消息之前,它们中的任何一个都会再次耗尽内存,并且程序会立即收到新内存OutOfMemoryError.
当我尝试第一个程序时,我确实看到了catch块生成的输出,这表明一旦抛出错误,程序执行是多么不可预测.在堆栈跟踪中,我看到在尝试为其创建新的后备数组时抛出了OOME ArrayList,这意味着仍有足够的内存来运行catch块.如果在创建较小的Long对象时抛出OOME,则可能会有所不同.
需要注意的重要一点是,您无法OutOfMemoryError以一种有意义的方式捕获错误:错误可能会在非常不方便的地方抛出,从而使内部数据结构处于不一致状态.在这种情况下,没有明显的不良影响,但如果你调查了内部字段,ArrayList你会发现它的modCount字段已经增加,而实际上没有修改列表.
| 归档时间: |
|
| 查看次数: |
93 次 |
| 最近记录: |