我遇到一个非常奇怪的问题,我想在SSCCE中重现,但我不能。
我正在使用Java8(32位)运行我的程序-Xmx1024m
,此代码使用加载了一个很大的文件(120MB)到字节数组中FileInputStream
。
问题是,尽管在Java6中我没有问题,但是在Java8中OutOfMemoryError
,只要尝试加载它就会获得异常。
我仍然有很多可用的内存,并且II已对其进行了概要分析,我认为没有问题。
如果我尝试在SSCCE中提取此问题,那么它将起作用。
我知道Oracle已经摆脱了PermGen,但是这可能会影响我的程序吗?
我还读到它可能与堆空间的碎片问题有关,但我尝试调试它,对其进行概要分析,并在分配内存之前从概要分析器运行GC周期,并且这种情况仍在发生(我假设GC周期将对堆空间进行碎片整理)
我想我找到了原因。根据此错误报告:
https://bugs.openjdk.java.net/browse/JDK-6478546
FileInputStream
将空间直接保留到本机内存中。当增加最大堆空间的大小时,实际上更糟,因为实际上本机映射的空间更少。
我的代码可以与Java8 64位一起使用的原因,恰恰是因为我从Windows获得了更多的虚拟空间,而在Windows中并没有被限制在大约1.7Gb。
我仍然不清楚,为什么相同的代码可以在Java6中工作。似乎同一应用程序在Java8中比在Java6中使用更多的本机空间。也许采用Metaspace的新方案使事情有所改变。我不知道。
有趣的文章:
http://www.codingthearchitecture.com/2008/01/14/jvm_lies_the_outofmemory_myth.html
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句