Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/337.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在Java中处理OutOfMemoryError?_Java_Memory Management - Fatal编程技术网

如何在Java中处理OutOfMemoryError?

如何在Java中处理OutOfMemoryError?,java,memory-management,Java,Memory Management,我必须序列化大约一百万个项目,当我运行代码时,会出现以下异常: Exception in thread "main" java.lang.OutOfMemoryError: Java heap space at java.util.Arrays.copyOfRange(Unknown Source) at java.lang.String.<init>(Unknown Source) at java.io.BufferedReader.readLine(Unk

我必须序列化大约一百万个项目,当我运行代码时,会出现以下异常:

Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
    at java.util.Arrays.copyOfRange(Unknown Source)
    at java.lang.String.<init>(Unknown Source)
    at java.io.BufferedReader.readLine(Unknown Source)
    at java.io.BufferedReader.readLine(Unknown Source)
    at org.girs.TopicParser.dump(TopicParser.java:23)
    at org.girs.TopicParser.main(TopicParser.java:59)
线程“main”java.lang.OutOfMemoryError中的异常:java堆空间 位于java.util.Arrays.copyOfRange(未知源) 位于java.lang.String。(未知源) 位于java.io.BufferedReader.readLine(未知源) 位于java.io.BufferedReader.readLine(未知源) 位于org.girs.TopicParser.dump(TopicParser.java:23) 位于org.girs.TopicParser.main(TopicParser.java:59)
我该怎么处理

使用选项-Xmx的较大值启动java,例如-Xmx512m

理想情况下,重新构造代码以使用较少的内存。例如,您可以将输出流化,而不是将整个内容保存在内存中


或者,只需使用
-Xmx
选项为JVM提供更多内存。

您不应该在代码中处理它。OutOfMemory不应被捕获和处理。相反,用更大的堆空间启动JVM

java -Xmx512M
我们应该做到这一点


有关更多详细信息,请参见。您可以使用-Xmx选项增加java使用的内存大小,例如:

java -Xmx512M -jar myapp.jar

更好的方法是减少应用程序的内存占用。你序列化了数百万项?你需要把它们都保存在内存中吗?或者你能在使用它们之后释放一些吗?尽量减少使用的对象。

您会遇到OutOfMemory错误,因为您的程序需要的内存比JVM可用的内存多。在运行时,您无法专门做任何事情来帮助实现这一点

正如krosenvold所指出的,您的应用程序可能对内存提出了合理的要求,但恰好JVM启动时内存不足(例如,您的应用程序将有280MB的峰值内存占用,但JVM启动时只有256MB)。在这种情况下,增加分配的大小将解决此问题

如果您觉得在启动时提供了足够的内存,那么您的应用程序可能暂时使用了太多内存,或者内存泄漏。在您发布的情况下,听起来好像您同时持有对内存中所有百万项的引用,即使您可能正在按顺序处理它们

检查“完成”的项目的引用是什么样的-你应该尽快遵从这些,以便它们可以被垃圾收集。例如,如果要向一个集合添加一百万个项,然后在该集合上迭代,则需要足够的内存来存储所有这些对象实例。看看是否可以一次获取一个对象,序列化它,然后放弃引用


如果您在解决此问题时遇到困难,发布一个伪代码片段会有所帮助。

使用transient关键字标记可从现有数据生成的序列化类中的字段。
实现writeObject和readObject,以帮助重建瞬态数据。

除了提供给您的一些提示之外,还可以查看内存不足和 还可以使用更多内存(-Xmx512M)启动JVM。 看起来您有OutOfMemoryError,因为您的TopicParser读取的行可能非常大(这是您应该避免的),您可以使用FileReader(或者,如果编码有问题,可以使用包装FileInputStream的InputStreamReader)。将其read(char[])方法与大小合理的char[]数组一起用作缓冲区

最后还要调查一下为什么可以使用OutOfMemoryError -XX:+HEAPDUMPONAUTOFMEMORYERROR JVM中的标志,以将转储堆信息获取到磁盘


祝你好运

没有真正的好办法处理它。一旦发生,你就处于未知的领域。您可以通过名称-OutOfMemoryError来判断。它被描述为:

当 Java虚拟机无法分配对象,因为该对象已过期 内存,垃圾箱无法提供更多内存 收集器

通常OutOfMemoryError表示系统/方法存在严重错误(很难指出触发它的特定操作)

通常情况下,这与heapspace的正常运行有关。使用-verbosegc和前面提到的-XX:+HeapDumpOnOutOfMemoryError应该会有所帮助


你可以在

上找到这个问题的简明摘要。我知道Java的官方答案是“哦,不!内存不足!我屈服了!”。对于那些在内存不足不允许成为致命错误(例如,编写操作系统或为不受保护的操作系统编写应用程序)的环境中编程的人来说,这都是相当令人沮丧的

放弃的意愿是必要的——您不能控制Java内存分配的每个方面,因此您不能保证您的程序在内存不足的情况下成功。但这并不意味着你必须不战而下

不过,在战斗之前,你可以想办法避免这种需要。也许您可以避免Java序列化,而是定义自己的数据格式,而不需要大量内存分配来创建。序列化分配了大量内存,因为它保留了以前看到的对象的记录,因此如果对象再次出现,它可以按编号引用它们,而不是再次输出它们(这可能导致无限循环)。但这是因为它需要通用性:根据您的数据结构,您可能能够定义一些文本/二进制/XML/任何表示形式,这些表示形式只需写入流,而不需要存储额外的状态。或者,您可以安排您需要的任何额外状态始终存储在对象中,而不是在序列化时创建

如果您的应用程序执行的某个操作占用大量内存,但大多数情况下占用的内存要少得多,特别是如果该操作是由用户启动的,并且如果您找不到使用更少内存或使更多内存可用的方法,那么它可能是值得的
catch (Throwable ex){
 if (!(ex instanceof ThreadDeath))
 {
  ex.printStackTrace(System.err);
 }}