在很多情况下,您可能希望抓住一个,根据我的经验(在Windows和Solaris JVM上),很少是JVM的丧钟。OutOfMemoryError
OutOfMemoryError
只有一个很好的理由来捕获,那就是优雅地关闭,干净利落地释放资源并尽可能地记录失败的原因(如果仍然可以这样做)。OutOfMemoryError
通常,发生这种情况是由于块内存分配无法满足堆的剩余资源。OutOfMemoryError
抛出 时,堆包含与分配不成功之前相同数量的已分配对象,现在是时候删除对运行时对象的引用,以释放清理可能需要的更多内存。在这些情况下,甚至可以继续,但这肯定是一个坏主意,因为您永远无法100%确定JVM处于可修复状态。Error
演示这并不意味着 JVM 在 catch 块中内存不足:OutOfMemoryError
private static final int MEGABYTE = (1024*1024);
public static void runOutOfMemory() {
MemoryMXBean memoryBean = ManagementFactory.getMemoryMXBean();
for (int i=1; i <= 100; i++) {
try {
byte[] bytes = new byte[MEGABYTE*500];
} catch (Exception e) {
e.printStackTrace();
} catch (OutOfMemoryError e) {
MemoryUsage heapUsage = memoryBean.getHeapMemoryUsage();
long maxMemory = heapUsage.getMax() / MEGABYTE;
long usedMemory = heapUsage.getUsed() / MEGABYTE;
System.out.println(i+ " : Memory Use :" + usedMemory + "M/" +maxMemory+"M");
}
}
}
此代码的输出:
1 : Memory Use :0M/247M
..
..
..
98 : Memory Use :0M/247M
99 : Memory Use :0M/247M
100 : Memory Use :0M/247M
如果运行一些关键的东西,我通常会抓住,将其记录到syserr,然后使用我选择的日志记录框架进行记录,然后继续释放资源并以干净的方式关闭。可能发生的最坏情况是什么?无论如何,JVM正在死亡(或已经死亡),并且通过捕获,至少有机会进行清理。Error
Error
需要注意的是,您必须仅在可以清理的地方捕获这些类型的错误。不要到处乱扔毯子,也不要胡说八道。catch(Throwable t) {}