观察Java中OutOfMemoryError的奇怪行为
我最近在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
请一些热情的人看一看并提出可能的解释好吗 提前谢谢 考虑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[]