简体   繁体   English

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

[英]How to avoid Java Heap Space Exception in java

I'm reading data from IO having huge volume of data and I need to store the data in key value pair in Map or properties file, then only I can use that data for generating reports. 我正在从具有大量数据的IO中读取数据,我需要将数据存储在Map或properties文件中的键值对中,然后只有我才能使用该数据来生成报告。 But when I am storing this huge data in Map or Properties file, Heap Memory Exception is coming.Instead, if I am using SQLLite its taking very huge time to retrieve that. 但是当我将大量数据存储在Map或Properties文件中时,将会出现堆内存异常,相反,如果我使用SQLLite,则将花费大量时间来检索它。 Is there any different way available to achieve this.Please suggest. 有什么其他方法可以实现这一目标。请提出建议。

Java Heap Space Important Points Java堆空间重要点

  1. Java Heap Memory is part of memory allocated to JVM by Operating System. Java堆内存是操作系统分配给JVM的内存的一部分。

  2. Whenever we create objects they are created inside Heap in Java. 每当我们创建对象时,它们都是在Java的Heap内部创建的。

  3. Java Heap space is divided into three regions or generation for sake of garbage collection called New Generation, Old or tenured Generation or Perm Space. 为了进行垃圾收集,将Java Heap空间分为三个区域或一代,称为“ New Generation”,“ Old”或“ tenured Generation”或“ Perm Space”。 Permanent generation is garbage collected during full gc in hotspot JVM. 永久生成是在热点JVM中进行完整gc期间收集的垃圾。

  4. You can increase or change size of Java Heap space by using JVM command line option -Xms, -Xmx and -Xmn. 您可以使用JVM命令行选项-Xms,-Xmx和-Xmn来增加或更改Java堆空间的大小。 don't forget to add word "M" or "G" after specifying size to indicate Mega or Gig. 在指定大小以表示Mega或Gig之后,不要忘记添加单词“ M”或“ G”。 For example you can set java heap size to 258MB by executing following command java -Xmx256m javaClassName (your program class name). 例如,您可以通过执行以下命令java -Xmx256m javaClassName(您的程序类名称)来将Java堆大小设置为258MB。

  5. You can use either JConsole or Runtime.maxMemory(), Runtime.totalMemory(), Runtime.freeMemory() to query about Heap size programmatic in Java. 您可以使用JConsole或Runtime.maxMemory(),Runtime.totalMemory(),Runtime.freeMemory()来查询有关Java中以编程方式编程的堆大小的信息。

  6. You can use command "jmap" to take Heap dump in Java and "jhat" to analyze that heap dump. 您可以使用命令“ jmap”来获取Java中的堆转储,而可以使用“ jhat”来分析该堆转储。

  7. Java Heap space is different than Stack which is used to store call hierarchy and local variables. Java Heap空间不同于用于存储调用层次结构和局部变量的Stack。

  8. Java Garbage collector is responsible for reclaiming memory from dead object and returning to Java Heap space. Java垃圾收集器负责从死对象中回收内存并返回Java堆空间。

  9. Don't panic when you get java.lang.OutOfMemoryError, sometimes it's just matter of increasing heap size but if it's recurrent then look for memory leak in Java. 当您遇到java.lang.OutOfMemoryError时不要惊慌,有时这只是增加堆大小的问题,但是如果经常发生,请在Java中查找内存泄漏。

  10. Use Profiler and Heap dump Analyzer tool to understand Java Heap space and how much memory is allocated to each object. 使用探查器和堆转储分析器工具可以了解Java堆空间以及为每个对象分配的内存量。

Reference link for more details: 参考链接以获取更多详细信息:

https://docs.oracle.com/cd/E19159-01/819-3681/abeii/index.html https://docs.oracle.com/cd/E19159-01/819-3681/abeii/index.html

https://docs.oracle.com/cd/E40520_01/integrator.311/integratoretl_users/src/ti_troubleshoot_memory_errors.html https://docs.oracle.com/cd/E40520_01/integrator.311/integratoretl_users/src/ti_troubleshoot_memory_errors.html

You need to do a rough estimate of of memory needed for your map. 您需要对地图所需的内存进行粗略估算。 How many keys and values? 多少个键和值? How large are keys and values? 键和值有多大? For example, if the keys are longs and values are strings 40 characters long on average, the absolute minimum for 2 billion key-value pairs is (40 + 8) * 2E9 - approximately 100 GB. 例如,如果键是long且值是平均40个字符长的字符串,则20亿个键值对的绝对最小值为(40 + 8)* 2E9-大约100 GB。 Of course, the real requirement is larger than the minimum estimate - as much as two times larger depending on the nature of the keys and values. 当然,实际要求比最小估计要大-取决于键和值的性质,最大要大两倍。

If the estimated amount of memory beyond reasonable (100 GB is beyond reasonable unless you have lots of money) you need to figure out a way to partition your processing. 如果估计的内存量超出合理范围(除非您有很多钱,否则100 GB超出合理范围),您需要找出一种对处理进行分区的方法。 You need to read in a large chunk of data, then run some algorithm on it to reduce it to some small size. 您需要读取大量数据,然后对其运行某种算法以将其减小到较小的大小。 Then do it for all other chunks one by one, making sure to not keeping the old chunk around when you process the new chunk. 然后对所有其他块一个接一个地处理,确保在处理新块时不要保留旧块。 Finally, look at the results from all chunks and compute the final result. 最后,查看所有块的结果并计算最终结果。 For a better description of this approach, look up "map-reduce'. 为了更好地说明这种方法,请查找“ map-reduce”。

If the estimated amount of memory is somewhat reasonable (say, 8 GB - and you have a 16 GB machine) - use 64 bit JVM, set the maximum heap memory using -Xmx switch, make sure you use the most efficient data structures such as Trove maps. 如果估计的内存量在某种程度上是合理的(例如8 GB,并且您有16 GB的计算机),请使用64位JVM,使用-Xmx开关设置最大堆内存,请确保使用最高效的数据结构,例如Trove地图。

Good luck! 祝好运!

增加堆大小是一种选择,但有通过使用java.You存储器映射文件可以引用存储断堆数据替代

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM