如何用junit3单元测试证明A类版本2的实例比版本1的内存效率更高?

时间:2012-02-09 19:26:14

标签: java unit-testing junit garbage-collection

我有一堆类,我必须调整以改善内存使用以换取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”少,表明在新类的内存分配过程中发生了某种奇怪的垃圾收集事件。

新类实例使用的内存结果显示结果从负数到正数,再次发信号通知在实例化过程中收集了一些奇怪的垃圾。

现在,有没有其他人试图证明某些课程比其他课程效率更高?这是一个非常酷的问题,但它仍然是一个问题。

谢谢,你们统治!

1 个答案:

答案 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");
}