您需要一种方法来检查类型选择对内存使用的影响。如果在给定情况下 short 与 int 将通过减少内存占用来获得性能,那么对内存的影响应该是可测量的。
这是一种测量正在使用的内存量的简单方法:
private static long inUseMemory() {
Runtime rt = Runtime.getRuntime();
rt.gc();
final long memory = rt.totalMemory() - rt.freeMemory();
return memory;
}
我还包括一个程序示例,该程序使用该方法检查某些常见情况下的内存使用情况。分配一百万个短数组的内存增加证实了短数组每个元素使用两个字节。各种对象数组的内存增加表明更改一个或两个字段的类型几乎没有区别。
这是一次运行的输出。YMMV。
Before short[1000000] allocation: In use: 162608 Change 162608
After short[1000000] allocation: In use: 2162808 Change 2000200
After TwoShorts[1000000] allocation: In use: 34266200 Change 32103392
After NoShorts[1000000] allocation: In use: 58162560 Change 23896360
After TwoInts[1000000] allocation: In use: 90265920 Change 32103360
Dummy to keep arrays live -378899459
本文其余部分为程序源码:
public class Test {
private static int BIG = 1000000;
private static long oldMemory = 0;
public static void main(String[] args) {
short[] megaShort;
NoShorts[] megaNoShorts;
TwoShorts[] megaTwoShorts;
TwoInts[] megaTwoInts;
System.out.println("Before short[" + BIG + "] allocation: "
+ memoryReport());
megaShort = new short[BIG];
System.out
.println("After short[" + BIG + "] allocation: " + memoryReport());
megaTwoShorts = new TwoShorts[BIG];
for (int i = 0; i < BIG; i++) {
megaTwoShorts[i] = new TwoShorts();
}
System.out.println("After TwoShorts[" + BIG + "] allocation: "
+ memoryReport());
megaNoShorts = new NoShorts[BIG];
for (int i = 0; i < BIG; i++) {
megaNoShorts[i] = new NoShorts();
}
System.out.println("After NoShorts[" + BIG + "] allocation: "
+ memoryReport());
megaTwoInts = new TwoInts[BIG];
for (int i = 0; i < BIG; i++) {
megaTwoInts[i] = new TwoInts();
}
System.out.println("After TwoInts[" + BIG + "] allocation: "
+ memoryReport());
System.out.println("Dummy to keep arrays live "
+ (megaShort[0] + megaTwoShorts[0].hashCode() + megaNoShorts[0]
.hashCode() + megaTwoInts[0].hashCode()));
}
private static long inUseMemory() {
Runtime rt = Runtime.getRuntime();
rt.gc();
final long memory = rt.totalMemory() - rt.freeMemory();
return memory;
}
private static String memoryReport() {
long newMemory = inUseMemory();
String result = "In use: " + newMemory + " Change "
+ (newMemory - oldMemory);
oldMemory = newMemory;
return result;
}
}
class NoShorts {
//char a, b, c;
}
class TwoShorts {
//char a, b, c;
short s, t;
}
class TwoInts {
//char a, b, c;
int s, t;
}