Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/324.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中OutOfMemoryError的奇怪行为_Java_Out Of Memory - Fatal编程技术网

观察Java中OutOfMemoryError的奇怪行为

观察Java中OutOfMemoryError的奇怪行为,java,out-of-memory,Java,Out Of Memory,我最近在Java中试验OutOfMemoryError,观察到下面提到的奇怪行为,对此我没有任何解释。 请一些热情的人看一看并提出可能的解释好吗 提前谢谢 考虑3次运行,每次运行如下: javac SimulateOOM.java java -Xmx100m -Xms100m SimulateOOM 运行1:按原样运行代码: 输出: 最后,线程中出现异常 “main”java.lang.OutOfMemoryError:java堆空间 位于SimulateOOM.main(SimulateOO

我最近在Java中试验OutOfMemoryError,观察到下面提到的奇怪行为,对此我没有任何解释。
请一些热情的人看一看并提出可能的解释好吗

提前谢谢

考虑3次运行,每次运行如下:

javac SimulateOOM.java
java -Xmx100m -Xms100m SimulateOOM
运行1:按原样运行代码:
输出:

最后,线程中出现异常 “main”java.lang.OutOfMemoryError:java堆空间
位于SimulateOOM.main(SimulateOOM.java:11)

Run2:注释掉语句1和取消注释语句2:
输出:

被抓住了
终于

运行3令人兴奋的部分)):恢复到原始代码,即注释掉语句2,取消注释语句1。此外,取消对语句块3的注释,即取消对语句块3之后出现的所有注释掉的语句的注释。
输出:

被抓住了
终于

根据我的观察,我有一些问题:
1) 当我们知道Throwable是OutOfMemoryError的超类时,运行2而不是运行1如何捕获异常 2) 取消注释某些代码(语句块3)怎么可能导致预期的Throwable行为能够捕获OOM?

import java.util.HashMap;
import java.util.Map;

public class SimulateOOM {
    public static void main(String[] args) {
        try {
            int i = 0;
            Map<Integer, Integer> mp = new HashMap<>();
            if (true) {
                while (true) {
                    mp.put(new Integer(i), new Integer(i+1000000));
                    i += 1;
                }
            }
        }
        catch (Throwable th) {          // ====== Statement 1 =====
        //catch (OutOfMemoryError e) {  // ====== Statement 2 =====
            System.err.println("Caught OOM!");
        }
        finally {
            System.err.println("In finally");
        }
    }

// ================= //
// Statement block 3
// ================= //
//    private static void simulateOOMCatchThrowable() {
//            try {
//            int i = 0;
//            Map<Integer, Integer> mp = new HashMap<>();
//            if (true) {
//                while (true) {
//                    mp.put(new Integer(i), new Integer(i+1000000));
//                    i += 1;
//                }
//            }
//        }
//        catch (Throwable th) {
//            System.err.println("Caught OOM!");
//        }
//        finally {
//            System.err.println("In finally");
//        }
//    }
//
//    private static void simulateOOMCatchOOM() {
//        try {
//            int i = 0;
//            Map<Integer, Integer> mp = new HashMap<>();
//            if (true) {
//                while (true) {
//                    mp.put(new Integer(i), new Integer(i+1000000));
//                    i += 1;
//                }
//            }
//        }
//        catch (OutOfMemoryError e) {
//            System.err.println("Caught OOM!");
//        }
//        finally {
//            System.err.println("In finally");
//        }
//    }
}
import java.util.HashMap;
导入java.util.Map;
公共类模拟对象{
公共静态void main(字符串[]args){
试一试{
int i=0;
Map mp=新的HashMap();
如果(真){
while(true){
mp.put(新整数(i),新整数(i+1000000));
i+=1;
}
}
}
catch(Throwable th){/==Statement 1=====
//catch(outofmemorye错误){/====语句2=====
System.err.println(“捕获OOM!”);
}
最后{
System.err.println(“In finally”);
}
}
// ================= //
//语句块3
// ================= //
//私有静态void SimulateOmCatchThrowable(){
//试一试{
//int i=0;
//Map mp=新的HashMap();
//如果(真){
//while(true){
//mp.put(新整数(i),新整数(i+1000000));
//i+=1;
//                }
//            }
//        }
//捕获(可丢弃){
//System.err.println(“捕获OOM!”);
//        }
//最后{
//System.err.println(“In finally”);
//        }
//    }
//
//私有静态void simulateOOMCatchOOM(){
//试一试{
//int i=0;
//Map mp=新的HashMap();
//如果(真){
//while(true){
//mp.put(新整数(i),新整数(i+1000000));
//i+=1;
//                }
//            }
//        }
//捕获(OutOfMemory错误){
//System.err.println(“捕获OOM!”);
//        }
//最后{
//System.err.println(“In finally”);
//        }
//    }
}

它是不可复制的。当我在'seq 1 100'中为I运行
时,do echo-n“$I:”;java-Xmx2m-Xms2m SimulateOOM;done;
我从100倍的输出中得到6倍的“捕获OOM!”,否则会出现
OutOfMemoryError
冒泡。因此,即使使用相同的代码,也可以得到不同的结果。如果'System.err.println(“捕获OOM!”);“导致另一个OOM?这将掩盖原始OOM和SysOut,只留下未捕获的OOM。”OOM@Progman感谢您的检查!我尝试了多次相同的100次跑步,但对我来说,它从未显示“抓到OOM”:(尽管上面给出了各种情况,但我觉得有些可疑!@DavidZimmerman可能会发生这种情况!为了消除这种情况,我创建了这些字符串作为静态最终类变量(以便在OOM之前分配内存),但仍然观察到相同的行为:(@Dikshant但println(String)可能分配内存,例如char[]