技术开发 频道

Java程序性能测试

5  内存消耗测试  
5.1  目标  
     当一个java应用程序运行时,有很多需要消耗内存的因素存在,像对象、加载类、线程等。在这里只考虑程序中的对象所消耗的虚拟机堆空间,这样我们就可以利用Runtime  类的freeMemory()和totalMemory()方法。  

5.2  实现  
为了方便期间,我们首先添加一个类计算当前内存消耗。  
class Memory { public static long used() { long total=Runtime.getRuntime().totalMemory(); long free=Runtime.getRuntime().freeMemory(); return (total-free); } }
然后修改Handler类的invoke()方法。  
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable ...{ Object result; try ...{ System.out.print("begin method " + method.getName() + "("); for (int i = 0; args != null && i < args.length; i++) ...{ if (i > 0) System.out.print(","); System.out.print(" " + args[i].toString()); } System.out.println(" )"); long start=Memory.used(); result = method.invoke(obj, args); long end=Memory.used(); System.out.println("memory increased by "+(end-start)+"bytes"); } catch (InvocationTargetException e) ...{ throw e.getTargetException(); } catch (Exception e) ...{ throw new RuntimeException("unexpected invocation exception: " + e.getMessage()); } finally ...{ System.out.println("end method " + method.getName()); } return result; }
同时我们的测试用例也做了一下改动,测试同样一个显而易见的问题,比较一个长度为1000的ArrayList和HashMap所占空间的大小,接口、实现如下:  
public interface MemoConsumer { public void creatArray(); public void creatHashMap(); } public class MemoConsumerImpl implements MemoConsumer { ArrayList arr=null; HashMap hash=null; public void creatArray() { arr=new ArrayList(1000); } public void creatHashMap() { hash=new HashMap(1000); } }
测试客户端代码如下:  
MemoConsumer arrayMemo=(MemoConsumer)Handler.newInstance(new MemoConsumerImpl ()); arrayMemo.creatArray(); arrayMemo.creatHashMap();
测试结果如下:  
begin method creatArray( ) memory increased by 4400bytes end method creatArray begin method creatHashMap( ) memory increased by 4480bytes end method creatHashMap
结果一幕了然,可以看到,我们只需要修改invoke()方法,然后简单执行客户端调用就可以了。  

6  结束语  
AOP通过分解关注点和OOP相得益彰,使程序更加简洁易懂,通过Java语言本身提供的动态代理帮助我们很容易分解关注点,取得了较好的效果。不过测试对象必须实现接口在一定程度上限制了动态代理的使用,可以借鉴Spring中使用的CGlib来为没有实现任何接口的类创建动态代理。  
0
相关文章