jy.*_*jy. 52 java exception out-of-memory
我正在开发一个需要大量内存的程序,我想在发生内存不足异常时捕获.我听说这是不可能做到的,但是如果在这方面有任何发展,我很好奇.
Chs*_*y76 84
这不是例外; 这是一个错误:java.lang.OutOfMemoryError
从Throwable下降时你可以捕获它:
try {
// create lots of objects here and stash them somewhere
} catch (OutOfMemoryError E) {
// release some (all) of the above objects
}
Run Code Online (Sandbox Code Playgroud)
但是,除非你正在做一些相当具体的事情(比如在特定的代码段中分配大量的东西),否则你可能无法捕获它,因为你不知道它会从哪里被抛出.
Sur*_*ran 53
这是可能的:
try {
// tragic logic created OOME, but we can blame it on lack of memory
} catch(OutOfMemoryError e) {
// but what the hell will you do here :)
} finally {
// get ready to be fired by your boss
}
Run Code Online (Sandbox Code Playgroud)
Ste*_*n C 25
您可以捕获并尝试从OutOfMemoryError(OOM)异常中恢复,但这可能是一个糟糕的想法 ...特别是如果您的目标是让应用程序"继续".
有许多的原因:
正如其他人所指出的那样,有更好的方法来管理内存资源而不是明确地释放内容; 即对内存较短时可以释放的对象使用SoftReference和WeakReference.
如果你等到实际耗尽内存之前你的应用程序,你的应用程序可能会花更多的时间来运行垃圾收集器.根据您的JVM版本和GC调整参数,JVM可能会越来越频繁地运行GC,因为它接近抛出OOM的点.减速(就应用程序做有用的工作而言)可能很重要.你可能想避免这种情况.
如果您的问题的根本原因是内存泄漏,那么从OOM捕获和恢复的可能性将无法回收泄漏的内存.您的应用程序将再次持续一段时间,然后再次,并再次减少间隔.
所以我的建议是不要试图继续从OOM出发...除非你知道:
小智 14
只是把它扔给那些思考为什么有人可能会耗尽内存的人:我正在研究一个经常耗尽内存的项目,我不得不为此实现一个解决方案.
该项目是取证和调查应用程序的一个组成部分.在现场收集数据(使用非常低的内存占用,顺便说一句)后,我们的调查应用程序中会打开数据.其中一个功能是对字段中捕获的任意二进制图像(来自物理内存的应用程序)执行CFG遍历.这些遍历可能需要很长时间,但会产生对遍历的二进制文件非常有用的可视化表示.
为了加快遍历过程,我们尝试尽可能多地保留物理内存中的数据,但数据结构随着二进制增长而增长,我们无法将其保留在内存中(目标是使用小于256米的java堆).那我该怎么办?
我创建了由磁盘支持的LinkedLists,Hashtables等版本,这些是对应的替代品,并实现了所有相同的接口,因此它们看起来与外界相同.
区别?这些替换结构彼此协作,消除内存错误并请求从最近最少使用的集合中最近最少使用的元素从存储器中释放.释放元素将其转储到临时文件(在系统提供的临时目录中)中的磁盘,并在适当的集合中将占位符对象标记为"分页".
在Java应用程序中可能会耗尽内存的大量原因 - 大多数原因的根源是以下一个或两个:1.应用程序在资源受限的计算机上运行(或尝试通过限制堆大小来限制资源使用)2.应用程序只需要大量内存(建议进行图像编辑,但音频和视频怎么样?在我的情况下编译器怎么样?没有非易失性存储的长期数据采集器怎么样?)
位
有可能捕获OutOfMemoryError
(它是一个Error
,而不是一个Exception
),但你应该知道,没有办法获得一个定义的行为.
在尝试捕获它时,您甚至可能会得到另一个OutOfMemoryError.
因此,更好的方法是创建/使用内存感知缓存.有一些框架(例如:JCS),但您可以使用SoftReference轻松构建自己的框架.有一篇关于如何在这里使用它的文章.按照文章中的链接获取更多信息.
这是可能的,但如果你用完了堆,它就不是很有用。如果有可以释放的资源,您最好使用 SoftReference 或 WeakReference 来释放这些资源,并且它们的清理将是自动的。
我发现如果您在由于某种原因无法自动触发 GC 之前耗尽直接内存,它会很有用。因此,如果我无法分配直接缓冲区,我就有理由强制执行GC。
当您专门分配可能太大的东西时,可能至少有一次抓住OutOfMemoryError的好时机:
public static int[] decode(InputStream in, int len) throws IOException {
int result[];
try {
result = new int[len];
} catch (OutOfMemoryError e) {
throw new IOException("Result too long to read into memory: " + len);
} catch (NegativeArraySizeException e) {
throw new IOException("Cannot read negative length: " + len);
}
...
}
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
81982 次 |
最近记录: |