简体   繁体   English

JVM内存不足

[英]JVM out of memory

I am implementing an external sort for a big file (~30GB), so after I have written the chunks in disk, I create chunks times BufferedReader(new OutputStreamWriter(new FileOutputStream(outputPath), "UTF-8"), maxBufferSize) being maxBufferSize = Runtime.getRuntime().freeMemory() / chunks . 我正在为一个大文件(〜30GB)实现一个外部排序,因此在将大块写入磁盘后,我创建了chunks时间BufferedReader(new OutputStreamWriter(new FileOutputStream(outputPath), "UTF-8"), maxBufferSize) maxBufferSize = Runtime.getRuntime().freeMemory() / chunks However I get a OutOfMemory Exception. 但是我收到了OutOfMemory异常。

I guess that the garbage collector didn't have time enough to clean the memory (when I stop with the debugger it does not throw the exception), but in that case, why Runtime.getRuntime().freeMemory() is given that result? 我猜垃圾回收器没有足够的时间来清理内存(当我停止使用调试器时,它不会引发异常),但是在那种情况下,为什么要给Runtime.getRuntime().freeMemory()结果?

Is it possible to explicitly call the garbage collection or the only option is sleep the process for some time? 是否可以显式调用垃圾回收或唯一的选择是将进程休眠一段时间?

Is it possible to explicitly call the garbage collection 是否可以显式调用垃圾回收

Yes it is possible. 对的,这是可能的。 But it won't do any good. 但这不会有任何好处。

The JVM will only throw an OOME after performing a full GC. JVM仅在执行完整的GC后才会抛出OOME。 Calling System.gc() explicitly will (most likely) just waste CPU time. 显式调用System.gc()很可能会浪费CPU时间。


Actually, I think your real problem is here: 实际上,我认为您的真正问题在这里:

I create chunks times BufferedReader(new OutputStreamWriter(new FileOutputStream(outputPath), "UTF-8"), maxBufferSize) being maxBufferSize = Runtime.getRuntime().freeMemory() / chunks . 我创建chunks时间BufferedReader(new OutputStreamWriter(new FileOutputStream(outputPath), "UTF-8"), maxBufferSize)maxBufferSize = Runtime.getRuntime().freeMemory() / chunks

When you consider the various object overheads, (maxBufferSize + overheads) * chunks is probably a bit greater than the amount of free memory. 考虑各种对象开销时, (maxBufferSize + overheads) * chunks可能比可用内存量大一点。

In general, it is a bad idea to run with a Java heap close to full. 通常,用接近满的Java堆运行是个坏主意。 Even if you don't run out of space entirely, you can find that running close to full will trigger many (too many) garbage collections. 即使您没有完全用完空间,也可以发现接近满容量将触发许多(太多)垃圾回收。

In this case, you don't really get a lot of benefit from having really large I/O buffers. 在这种情况下,拥有非常大的I / O缓冲区并不会真正带来很多好处。 Buffers in the range of 8KB to 64KB should be fine ... is my gut feeling. 我的直觉是8KB到64KB范围内的缓冲区应该没问题。 See also Peter Lawrey's comment! 另请参阅Peter Lawrey的评论!

You can try using System.gc() , but its not the most useful. 您可以尝试使用System.gc() ,但它不是最有用的。 You could try giving the program more memory. 您可以尝试给程序更多的内存。

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

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