我有一堆类,我必须调整以改善内存使用以换取CPU时间,并且我有junit 3作为测试框架来证明它。
虽然我可以很容易地做到这一点(在一个字节中使用string.getBytes("UTF-8");
填充多个布尔值,使用long而不是Date,实现我自己的集合等),我真的没有一个可靠的方法来显示改进的时候我提交代码,因为垃圾收集器具有不可预测的性质。
当我谈论收集垃圾时,我的意思是我已经完成了这两件事:称为System.gc()
,并试图像这样分配一个数组long[] longs=new long[Integer.MAX_VALUE];
这些是我试图实现但没有成功的几个算法:
1:
a:垃圾收集;
b:获取此时使用的内存量; (long beforeold=Runtime.getRuntime().maxMemory - Runtime.getRuntime().freeMemory();
)
c:分配一个包含几万个旧类实例的数组;
d:垃圾收集;
f:long afterold=Runtime.getRuntime().maxMemory - Runtime.getRuntime().freeMemory();
g:重复实例化新类的过程
h:比较内存的差异。
我得到的结果非常奇怪: 我的“afterold”比我的“beforeold”少,表明在新类的内存分配过程中发生了某种奇怪的垃圾收集事件。
新类实例使用的内存结果显示结果从负数到正数,再次发信号通知在实例化过程中收集了一些奇怪的垃圾。
现在,有没有其他人试图证明某些课程比其他课程效率更高?这是一个非常酷的问题,但它仍然是一个问题。
谢谢,你们统治!
答案 0 :(得分:0)
Heinz Kabutz在Java专家时事通讯中有一些提示:http://www.javaspecialists.eu/archive/Issue193.html:
public long calculateMemoryUsage(ObjectFactory factory) {
Object handle = factory.makeObject();
long memory = usedMemory();
handle = null;
lotsOfGC();
memory = usedMemory();
handle = factory.makeObject();
lotsOfGC();
return usedMemory() - memory;
}
private long usedMemory() {
return Runtime.getRuntime().totalMemory() -
Runtime.getRuntime().freeMemory();
}
private void lotsOfGC() {
for (int i = 0; i < 20; i++) {
System.gc();
try {
Thread.sleep(100);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
}
public void showMemoryUsage(ObjectFactory factory) {
long mem = calculateMemoryUsage(factory);
System.out.println(
factory.getClass().getSimpleName() + " produced " +
factory.makeObject().getClass().getSimpleName() +
" which took " + mem + " bytes");
}