gpt4 book ai didi

java - 关于 OutOfMemoryError 及其处理方法

转载 作者:行者123 更新时间:2023-12-02 00:52:04 24 4
gpt4 key购买 nike

经过反复试验,我了解到 11_451_104 是一个神奇的数字,它会导致我的机器抛出 OOM 错误。

使用11_451_103,我打包了尽可能多的数据。

private static void init() {
int i = 0;
try {
while (++i < 11451104) {
list.add("a");
}
} catch (OutOfMemoryError e) {
System.out.println("oh no, not again :("); // <-- Not getting here
}
}

如果在下一行我这样做

    String x = "some new string";

我预计会发生异常,因为堆无法为另外 1 个字符串分配空间。然而,事实并非如此。

如果我尝试将这个新字符串添加到列表中,

    String x = "some new string"; // <-- expect OOM Error to happen here
list.add(x);

程序因 OOM 而中止。 为什么在字符串分配时没有发生这种情况?

知道可能存在 OOM,因为可能需要保存未知(可能非常大)的数据量,如何最好地保护自己?序列化和持久化到磁盘是处理这个问题的方法吗?

最佳答案

Why did not this happen upon string allocation?

list.add(...) 方法也可能正在分配内存。如果列表是 LinkedList,则每个 add 调用都会创建一个新的列表节点。如果它是 ArrayList,则 add 可能会导致后备数组被重新分配。

(更新 - 我刚刚注意到您甚至没有创建新的字符串对象。您不断地将相同的文字字符串 "a" 添加到列表中,并且保证 OOME 不会在字符串分配中发生!)

How to best protect oneself knowing that OOM is a possibility ...

try catch OOME 并从中恢复是很诱人的,但这可能存在风险。问题是您永远无法确定您的应用程序(例如应用程序代码调用的某些库方法)实际上正在尝试分配什么,以及 Error 是否发生在不方便的时间并已离开一些重要的数据结构处于部分或不一致的状态。因此,您的应用程序可能不适合尝试恢复。

一般来说,当您收到 OOME 时,最安全的做法是立即退出应用程序。不要尝试提交事务等。当应用程序的数据库连接套接字/管道/任何内容被操作系统关闭时,让数据库的自动回滚清理所有未提交的事务。

事实上,“不要尝试恢复”建议适用于所有 Error 异常。只是在 OOME 中,开发人员倾向于忽略建议,因为他们认为自己更了解......

<小时/>

就“保护自己”而言,一般的解决方案是将重要状态的副本安全地保存在非 volatile 存储上;例如通过将其写入数据库、序列化为平面文件等。具体细节(例如哪种技术最好)将取决于数据、应用程序如何使用它以及如何使应用程序可重新启动。

问题/情况与处理可能的应用程序崩溃、操作系统重新启动、电源故障等问题没有本质上的不同。

关于java - 关于 OutOfMemoryError 及其处理方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11355138/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com