JVM 内存不足
JVM out of memory
我正在为一个大文件 (~30GB) 实施外部排序,因此在我将块写入磁盘后,我创建 chunks
次 BufferedReader(new OutputStreamWriter(new FileOutputStream(outputPath), "UTF-8"), maxBufferSize)
为 maxBufferSize = Runtime.getRuntime().freeMemory() / chunks
。但是我得到一个 OutOfMemory
异常。
我猜垃圾收集器没有足够的时间来清理内存(当我停止使用调试器时它不会抛出异常),但在那种情况下,为什么给出 Runtime.getRuntime().freeMemory()
结果?
是否可以显式调用垃圾回收,或者唯一的选择是让进程休眠一段时间?
您可以尝试使用 System.gc()
,但它不是最有用的。你可以尝试给程序更多的内存。
Is it possible to explicitly call the garbage collection
是的,这是可能的。但它不会有任何好处。
JVM 只会在执行完整 GC 后抛出 OOME。显式调用 System.gc()
将(很可能)只会浪费 CPU 时间。
其实我觉得你真正的问题是:
I create chunks
times BufferedReader(new OutputStreamWriter(new FileOutputStream(outputPath), "UTF-8"), maxBufferSize)
being maxBufferSize = Runtime.getRuntime().freeMemory() / chunks
.
当您考虑各种对象开销时,(maxBufferSize + overheads) * chunks
可能比空闲内存量大一点。
一般来说,运行 堆接近满时 Java 是个坏主意。即使您没有 运行 完全超出 space,您也会发现 运行 接近满时会触发许多(太多)垃圾回收。
在这种情况下,拥有非常大的 I/O 缓冲区并不会真正让您受益匪浅。 8KB 到 64KB 范围内的缓冲区应该没问题……这是我的直觉。另请参阅 Peter Lawrey 的评论!
我正在为一个大文件 (~30GB) 实施外部排序,因此在我将块写入磁盘后,我创建 chunks
次 BufferedReader(new OutputStreamWriter(new FileOutputStream(outputPath), "UTF-8"), maxBufferSize)
为 maxBufferSize = Runtime.getRuntime().freeMemory() / chunks
。但是我得到一个 OutOfMemory
异常。
我猜垃圾收集器没有足够的时间来清理内存(当我停止使用调试器时它不会抛出异常),但在那种情况下,为什么给出 Runtime.getRuntime().freeMemory()
结果?
是否可以显式调用垃圾回收,或者唯一的选择是让进程休眠一段时间?
您可以尝试使用 System.gc()
,但它不是最有用的。你可以尝试给程序更多的内存。
Is it possible to explicitly call the garbage collection
是的,这是可能的。但它不会有任何好处。
JVM 只会在执行完整 GC 后抛出 OOME。显式调用 System.gc()
将(很可能)只会浪费 CPU 时间。
其实我觉得你真正的问题是:
I create
chunks
timesBufferedReader(new OutputStreamWriter(new FileOutputStream(outputPath), "UTF-8"), maxBufferSize)
beingmaxBufferSize = Runtime.getRuntime().freeMemory() / chunks
.
当您考虑各种对象开销时,(maxBufferSize + overheads) * chunks
可能比空闲内存量大一点。
一般来说,运行 堆接近满时 Java 是个坏主意。即使您没有 运行 完全超出 space,您也会发现 运行 接近满时会触发许多(太多)垃圾回收。
在这种情况下,拥有非常大的 I/O 缓冲区并不会真正让您受益匪浅。 8KB 到 64KB 范围内的缓冲区应该没问题……这是我的直觉。另请参阅 Peter Lawrey 的评论!