Chr*_*ing 5 java memory arrays out-of-memory large-data
我希望创建一个大型的int数组,它几乎可以填充JVM可用的所有内存.以此代码为例:
final int numBuffers = (int) ((runtime.freeMemory() - 200000L) / (BUFFER_SIZE));
System.out.println(runtime.freeMemory());
System.out.println(numBuffers*(BUFFER_SIZE/4)*4);
buffers = new int[numBuffers*(BUFFER_SIZE / 4)];
Run Code Online (Sandbox Code Playgroud)
当堆大小为10M运行时,抛出OutOfMemoryException,尽管printlns的输出为:
9487176
9273344
Run Code Online (Sandbox Code Playgroud)
我意识到阵列会有一些开销,但肯定不是200k?为什么java无法为声称有足够空间的东西分配内存?我必须设置在Java运行之前减去4M左右的常量(此时printlns看起来更像是:9487176 5472256)
更令人困惑的是,如果我用2D数组替换缓冲区:
buffers = new int[numBuffers][BUFFER_SIZE / 4];
Run Code Online (Sandbox Code Playgroud)
然后使用上面显示的200k减法运行没有抱怨 - 即使两个数组中存储的整数量相同(并且2D阵列上的开销不会大于1D阵列的开销,因为它全部都是那些对要存储的其他数组的引用).
有任何想法吗?
VM会将堆内存划分到不同的区域(主要用于垃圾收集器),因此当您尝试分配几乎整个堆大小的单个对象时,将耗尽内存.
此外,一些内存已经被JRE用完了.200k 与今天的内存大小无关,对于大多数应用程序来说,10M堆几乎是不切实际的小.
数组的实际开销相对较小,在32位VM上它的12字节IIRC(如果大小小于最小粒度(即AFAIK 8字节),则加上浪费的东西).因此,在最坏的情况下,每个阵列的开销大约为19字节.
请注意,Java没有2D(多维)数组,它在内部实现为数组数组.
| 归档时间: |
|
| 查看次数: |
1034 次 |
| 最近记录: |