Java中如何避免Java堆空间异常

Java中如何避免Java堆空间异常,java,jvm,out-of-memory,Java,Jvm,Out Of Memory,我从IO读取数据,数据量很大,我需要将数据存储在映射或属性文件中的键值对中,然后只有我可以使用该数据生成报告。但当我将这些巨大的数据存储在映射或属性文件中时,堆内存异常就会出现。相反,如果我使用SQLLite,检索这些数据会花费非常长的时间。是否有其他方法可以实现这一点。请建议。增加堆大小是一种选择,但也有另一种方法可以通过使用java中的内存映射文件来存储堆外数据。您可以参考java堆空间的要点 Java堆内存是操作系统分配给JVM的内存的一部分 无论何时我们创建对象,它们都是在Java的堆中

我从IO读取数据,数据量很大,我需要将数据存储在映射或属性文件中的键值对中,然后只有我可以使用该数据生成报告。但当我将这些巨大的数据存储在映射或属性文件中时,堆内存异常就会出现。相反,如果我使用SQLLite,检索这些数据会花费非常长的时间。是否有其他方法可以实现这一点。请建议。

增加堆大小是一种选择,但也有另一种方法可以通过使用java中的内存映射文件来存储堆外数据。您可以参考java堆空间的要点

  • Java堆内存是操作系统分配给JVM的内存的一部分

  • 无论何时我们创建对象,它们都是在Java的堆中创建的

  • 为了进行垃圾收集,Java堆空间分为三个区域或一代,称为新一代、旧一代或永久一代或永久一代。在hotspot JVM中的完全gc期间,永久生成是垃圾收集的

  • 您可以使用JVM命令行选项-Xms、-Xmx和-Xmn来增加或更改Java堆空间的大小。不要忘了在指定大小后添加单词“M”或“G”,以表示Mega或Gig。 例如,您可以通过执行以下命令java-xmx256mjavaclassname(您的程序类名),将java堆大小设置为258MB

  • 您可以使用JConsole或Runtime.maxMemory()、Runtime.totalMemory()、Runtime.freemory()查询Java编程的堆大小

  • 您可以使用命令“jmap”在Java中获取堆转储,并使用“jhat”分析该堆转储

  • Java堆空间不同于用于存储调用层次结构和局部变量的堆栈

  • Java垃圾收集器负责从死对象中回收内存并返回Java堆空间

  • 当您得到java.lang.OutOfMemoryError时,不要惊慌,有时这只是增加堆大小的问题,但如果它是反复出现的,那么请在java中查找内存泄漏

  • 使用探查器和堆转储分析器工具了解Java堆空间以及分配给每个对象的内存量

  • 有关更多详细信息,请参考链接:


    您需要粗略估计地图所需的内存。有多少个键和值?键和值有多大?例如,如果键是长的,值是平均长度为40个字符的字符串,则20亿个键值对的绝对最小值为(40+8)*2E9-大约100 GB。当然,实际需求比最低估计值大——根据键和值的性质,实际需求比最低估计值大两倍

    如果估计的内存量超出了合理范围(100 GB超出了合理范围,除非你有很多钱),那么你需要找到一种划分处理的方法。您需要读入一大块数据,然后对其运行一些算法以将其缩小到较小的大小。然后一个接一个地处理所有其他块,确保在处理新块时不要保留旧块。最后,查看所有块的结果并计算最终结果。要更好地描述这种方法,请查阅“map reduce”

    如果估计的内存量比较合理(例如,8GB—您有一台16GB的机器)—使用64位JVM,使用-Xmx开关设置最大堆内存,确保使用最有效的数据结构,如Trove映射


    祝你好运!

    在这种情况下,如果我们增加堆,问题仍然存在。请建议我不增加堆的任何不同方法。你可以做的是读取字节块中的数据,将其存储在地图上,然后进一步处理。从你的问题中我可以看出,你正在读取大量数据,并将其存储在m中当您处理大量数据并充分利用JVM时,请立即使用ap或属性文件。这可能是导致堆空间异常的原因。请尝试使用chunksNo Sir。我们正在为jasper报表读取数据。因此,在读取整个数据后,我们只能进行数据填充。因此,字节块无法应用于h这里。还有其他建议吗,先生。如果你只有5个苹果的空间,你就不能储存10个苹果。这根本不可能。在我们的例子中,我们正在从蜂巢读取数据,并试图将数据放入地图或根据一些匹配的条件。阅读完文件后,我们可以使用RandomAccessFile进行建议,先生。