尝试捕捉内存异常有多好?我没有任何在低级管理自己内存的软件的编写经验,但我可以想象一种方法来做到这一点。
我不知道Java实际如何处理内存异常。管理内存的程序有可能耗尽内存吗?我什么时候可以尝试捕捉内存不足的异常,而它却无法捕获异常?
谢谢!
发布于 2014-02-08 10:25:52
尝试捕捉内存异常有多好?
在某种程度上很好..。但在另一个层面上,这可能是冒险和/或徒劳的。见下文。
管理内存的程序有可能耗尽内存吗?
管理内存的“程序”是垃圾收集器。AFAIK,它总是有足够的内存用于自己的目的。不过,如果它不这样做,它将别无选择,只能硬崩溃JVM。
我什么时候可以尝试捕捉内存不足的异常,而它却无法捕获异常?
只有当JVM崩溃时。或者,如果OOME抛出的线程堆栈与试图捕获它的线程堆栈不同。
好吧,那么为什么抓OOME是危险的和/或徒劳的。
第一个原因是可以在没有任何警告的情况下在任何线程堆栈上抛出OOME。当您捕获异常时,处理程序(通常)无法知道“上堆栈”发生了什么,以及它是如何失败的。因此,它无法知道应用程序的执行状态是否已损坏或受损。(线程是否正在更新一些重要的内容?它是要通知其他线程..。而线程现在将永远得不到通知?)
第二个原因是OOME通常是Java存储泄漏的结果.在不应该做的情况下,由“坚持”对象造成的。如果你抓到一个OOME并试图恢复..。当问题是由泄漏引起的..。很有可能冒犯的对象仍然是可访问的,而另一个OOME很快就会跟进。换句话说,您的应用程序可能会陷入不断从OOME中抛出和恢复的状态。充其量这会扼杀表演..。因为JVM在OOME之前通常做的最后一件事是执行一个完整的(停止世界)垃圾收集。这需要相当长的时间。
注意,这并不是说你永远不应该抓住OOME。事实上,抓住一个OOME,报告它,然后关闭通常是一个好的策略。
不,危险/徒劳的是抓住OOME,然后尝试恢复并继续运行。
发布于 2014-02-08 07:29:29
您不必担心任何隐式分配,而这些分配本身就是捕捉可抛出的分配的一部分。抓住他们总是有可能的。JVM甚至让预先分配的OOM错误实例在出现故障时可用,这样它们本身就不会失败分配。
然而,很可能会有次要的问题:
LogRecord
或StringBuilder
,后者甚至可能作为语法字符串连接的一部分隐式发生),这可能会再次耗尽内存。然而,这些问题只适用于内存不足的“正常方式”,即分配大量“正常”对象。相反,如果内存不足的操作是例如10 GB数组的单个分配,那么它们就不会造成问题。
发布于 2014-02-08 07:29:07
在java中,内存不足不是一个异常,而是一个错误。您可以在程序级别上做任何事情,但这是一个系统限制。您可以通过增加默认堆内存大小来转义它。
export JVM_ARGS="-Xmx1024m -XX:MaxPermSize=256m"
https://stackoverflow.com/questions/21643225
复制相似问题