我听过关于Java程序中一个字节占用的内存量的意见不一。
我知道您在一个Java字节中最多可以存储+127,并且文档说一个字节只有8位,但是在这里我被告知实际上它占用的内存量与int相同,因此仅一种有助于代码理解而不是效率的类型。
谁能解决这个问题,这将是实现特定的问题吗?
好的,已经进行了很多讨论,而没有很多代码:)
这是一个快速基准测试。谈到这种事情,通常会有一些警告-测试内存由于JITting等原因而有些奇怪,但是如果数量合适,反正还是很有用的。它有两种类型,每种类型都有80个成员-LotsOfBytes具有80个字节,LotsOfInts具有80个int。我们构建了很多它们,确保它们没有被GC处理,并检查内存使用情况:
class LotsOfBytes { byte a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, aa, ab, ac, ad, ae, af; byte b0, b1, b2, b3, b4, b5, b6, b7, b8, b9, ba, bb, bc, bd, be, bf; byte c0, c1, c2, c3, c4, c5, c6, c7, c8, c9, ca, cb, cc, cd, ce, cf; byte d0, d1, d2, d3, d4, d5, d6, d7, d8, d9, da, db, dc, dd, de, df; byte e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, ea, eb, ec, ed, ee, ef; } class LotsOfInts { int a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, aa, ab, ac, ad, ae, af; int b0, b1, b2, b3, b4, b5, b6, b7, b8, b9, ba, bb, bc, bd, be, bf; int c0, c1, c2, c3, c4, c5, c6, c7, c8, c9, ca, cb, cc, cd, ce, cf; int d0, d1, d2, d3, d4, d5, d6, d7, d8, d9, da, db, dc, dd, de, df; int e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, ea, eb, ec, ed, ee, ef; } public class Test { private static final int SIZE = 1000000; public static void main(String[] args) throws Exception { LotsOfBytes[] first = new LotsOfBytes[SIZE]; LotsOfInts[] second = new LotsOfInts[SIZE]; System.gc(); long startMem = getMemory(); for (int i=0; i < SIZE; i++) { first[i] = new LotsOfBytes(); } System.gc(); long endMem = getMemory(); System.out.println ("Size for LotsOfBytes: " + (endMem-startMem)); System.out.println ("Average size: " + ((endMem-startMem) / ((double)SIZE))); System.gc(); startMem = getMemory(); for (int i=0; i < SIZE; i++) { second[i] = new LotsOfInts(); } System.gc(); endMem = getMemory(); System.out.println ("Size for LotsOfInts: " + (endMem-startMem)); System.out.println ("Average size: " + ((endMem-startMem) / ((double)SIZE))); // Make sure nothing gets collected long total = 0; for (int i=0; i < SIZE; i++) { total += first[i].a0 + second[i].a0; } System.out.println(total); } private static long getMemory() { Runtime runtime = Runtime.getRuntime(); return runtime.totalMemory() - runtime.freeMemory(); } }
在我的盒子上输出:
Size for LotsOfBytes: 88811688 Average size: 88.811688 Size for LotsOfInts: 327076360 Average size: 327.07636 0
因此,显然存在一些开销-从外观上看为8个字节,尽管不知何故LotsOfInts只有7个字节(如我所说,这里有些奇怪)-但问题是字节字段似乎被打包成LotsOfBytes的样子, (除去开销后)仅占用LotsOfInts内存的四分之一。