首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >Java尝试内存捕获

Java尝试内存捕获
EN

Stack Overflow用户
提问于 2014-02-08 07:21:13
回答 5查看 1.5K关注 0票数 4

尝试捕捉内存异常有多好?我没有任何在低级管理自己内存的软件的编写经验,但我可以想象一种方法来做到这一点。

我不知道Java实际如何处理内存异常。管理内存的程序有可能耗尽内存吗?我什么时候可以尝试捕捉内存不足的异常,而它却无法捕获异常?

谢谢!

EN

回答 5

Stack Overflow用户

回答已采纳

发布于 2014-02-08 10:25:52

尝试捕捉内存异常有多好?

在某种程度上很好..。但在另一个层面上,这可能是冒险和/或徒劳的。见下文。

管理内存的程序有可能耗尽内存吗?

管理内存的“程序”是垃圾收集器。AFAIK,它总是有足够的内存用于自己的目的。不过,如果它不这样做,它将别无选择,只能硬崩溃JVM。

我什么时候可以尝试捕捉内存不足的异常,而它却无法捕获异常?

只有当JVM崩溃时。或者,如果OOME抛出的线程堆栈与试图捕获它的线程堆栈不同。

好吧,那么为什么抓OOME是危险的和/或徒劳的。

第一个原因是可以在没有任何警告的情况下在任何线程堆栈上抛出OOME。当您捕获异常时,处理程序(通常)无法知道“上堆栈”发生了什么,以及它是如何失败的。因此,它无法知道应用程序的执行状态是否已损坏或受损。(线程是否正在更新一些重要的内容?它是要通知其他线程..。而线程现在将永远得不到通知?)

第二个原因是OOME通常是Java存储泄漏的结果.在不应该做的情况下,由“坚持”对象造成的。如果你抓到一个OOME并试图恢复..。当问题是由泄漏引起的..。很有可能冒犯的对象仍然是可访问的,而另一个OOME很快就会跟进。换句话说,您的应用程序可能会陷入不断从OOME中抛出和恢复的状态。充其量这会扼杀表演..。因为JVM在OOME之前通常做的最后一件事是执行一个完整的(停止世界)垃圾收集。这需要相当长的时间。

注意,这并不是说你永远不应该抓住OOME。事实上,抓住一个OOME,报告它,然后关闭通常是一个好的策略。

不,危险/徒劳的是抓住OOME,然后尝试恢复并继续运行。

票数 1
EN

Stack Overflow用户

发布于 2014-02-08 07:29:29

您不必担心任何隐式分配,而这些分配本身就是捕捉可抛出的分配的一部分。抓住他们总是有可能的。JVM甚至让预先分配的OOM错误实例在出现故障时可用,这样它们本身就不会失败分配。

然而,很可能会有次要的问题:

  • 任何分配都可能是打破骆驼背的一根稻草,因此您可能不知道您的代码将在哪里抛出OOM错误。它甚至可能发生在与您正在执行的内存消耗工作完全不同的线程中,从而导致JVM中完全不同的部分崩溃。
  • 取决于捕获时要做什么,您可能会分配更多的内存(例如LogRecordStringBuilder,后者甚至可能作为语法字符串连接的一部分隐式发生),这可能会再次耗尽内存。

然而,这些问题只适用于内存不足的“正常方式”,即分配大量“正常”对象。相反,如果内存不足的操作是例如10 GB数组的单个分配,那么它们就不会造成问题。

票数 2
EN

Stack Overflow用户

发布于 2014-02-08 07:29:07

在java中,内存不足不是一个异常,而是一个错误。您可以在程序级别上做任何事情,但这是一个系统限制。您可以通过增加默认堆内存大小来转义它。

代码语言:javascript
运行
复制
export JVM_ARGS="-Xmx1024m -XX:MaxPermSize=256m"
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/21643225

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档