1 /*** 2 * ASM performance test: measures the performances of asm package 3 * Copyright (c) 2002-2005 France Telecom 4 * All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 3. Neither the name of the copyright holders nor the names of its 15 * contributors may be used to endorse or promote products derived from 16 * this software without specific prior written permission. 17 * 18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 19 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 22 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 26 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 28 * THE POSSIBILITY OF SUCH DAMAGE. 29 */ 30 package org.objectweb.asm; 31 32 import java.io.FileInputStream; 33 import java.io.FileNotFoundException; 34 import java.io.IOException; 35 import java.util.ArrayList; 36 import java.util.Iterator; 37 import java.util.LinkedList; 38 import java.util.List; 39 import java.util.jar.JarEntry; 40 import java.util.jar.JarInputStream; 41 42 import org.objectweb.asm.ClassReader; 43 import org.objectweb.asm.tree.ClassNode; 44 import org.objectweb.asm.tree.MethodNode; 45 46 /* 47 * Created on Nov 30, 2004 as part of ASMPerf by treffer 48 */ 49 50 /** 51 * Memory performances tests for tree package. 52 * 53 * @author treffer 54 */ 55 public class ASMMemTest { 56 57 public static void main(String[] args) { 58 if (args.length < 2) { 59 System.out.println("java ASMMemTest <jar-file> <number-of-classes>"); 60 System.exit(1); 61 } 62 63 Runtime runtime = Runtime.getRuntime(); 64 memDown(runtime); 65 System.out.println("Initial memory load: ".concat(memFormat(getUsedMem(runtime)))); 66 67 LinkedList fileData = new LinkedList(); 68 int limit = Integer.parseInt(args[1]); 69 try { 70 long totalSize = 0; 71 JarInputStream jar = new JarInputStream(new FileInputStream(args[0])); 72 JarEntry entry = jar.getNextJarEntry(); 73 while ((fileData.size() < limit) && (entry != null)) { 74 String name = entry.getName(); 75 if (name.endsWith(".class")) { 76 if (entry.getSize() != -1) { 77 int len = (int) entry.getSize(); 78 byte[] data = new byte[len]; 79 jar.read(data); 80 fileData.add(data); 81 totalSize += data.length; 82 } else { 83 System.err.println("No jar-entry size given... Unimplemented, jar file not supported"); 84 } 85 } 86 entry = jar.getNextJarEntry(); 87 } 88 System.out.println(memFormat(totalSize) + " class data, ~" 89 + memFormat(totalSize / limit) + " per class."); 90 } catch (FileNotFoundException e) { 91 e.printStackTrace(); 92 } catch (IOException e) { 93 e.printStackTrace(); 94 } 95 96 ArrayList result = new ArrayList(fileData.size()); 97 long startmem; 98 99 for (int i = 0; i < 10; i++) { 100 System.out.println("\n> Run ".concat(Integer.toString(i + 1))); 101 Iterator files = fileData.iterator(); 102 result.clear(); 103 memDown(runtime); 104 System.out.println("Empty memory load: ".concat(memFormat(startmem = getUsedMem(runtime)))); 105 106 long time = -System.currentTimeMillis(); 107 while (files.hasNext()) { 108 byte data[] = (byte[]) files.next(); 109 ClassReader reader = new ClassReader(data); 110 ClassNode clazz = new ClassNode(); 111 reader.accept(clazz, false); 112 result.add(clazz); 113 } 114 time += System.currentTimeMillis(); 115 116 memDown(runtime); 117 System.out.println("Time: ".concat(timeFormat(time))); 118 System.out.println("Final memory load: ".concat(memFormat(getUsedMem(runtime)))); 119 System.out.println("ASM memory load: ".concat(memFormat(getUsedMem(runtime) 120 - startmem))); 121 for (int j = 0; j < limit; j++) { 122 ClassNode clazz = (ClassNode) result.get(j); 123 List l = clazz.methods; 124 for (int k = 0, lim = l.size(); k < lim; k++) { 125 MethodNode m = (MethodNode) l.get(k); 126 List insn = m.instructions; 127 if (insn != null) 128 insn.clear(); 129 /* 130 * for (int ins = 0, insmax = insn.size(); ins < insmax; 131 * ins++) { if (insn.get(ins) instanceof VarInsnNode) { 132 * insn.set(ins, null); } } 133 */ 134 } 135 } 136 memDown(runtime); 137 System.out.println("ASM memory load (removed method code): ".concat(memFormat(getUsedMem(runtime) 138 - startmem))); 139 } 140 141 } 142 143 public final static long getUsedMem(final Runtime r) { 144 return r.totalMemory() - r.freeMemory(); 145 } 146 147 public final static String timeFormat(final long time) { 148 int min = (int) (time / (60 * 1000)); 149 int sec = (int) ((time / (1000)) % 60); 150 int msec = (int) (time % 1000); 151 StringBuffer sbuf = new StringBuffer(30); 152 if (min > 0) { 153 sbuf.append(min); 154 sbuf.append("min "); 155 } 156 if ((sec > 0) || (min > 0)) { 157 sbuf.append(sec); 158 sbuf.append("s "); 159 } 160 if ((msec > 0) || (sec > 0) || (min > 0)) { 161 sbuf.append(msec); 162 sbuf.append("ms "); 163 } 164 sbuf.append("("); 165 sbuf.append(time); 166 sbuf.append("ms)"); 167 return sbuf.toString(); 168 } 169 170 public final static String memFormat(final long mem) { 171 int gb = (int) ((mem >> 30) & 0x3FF); 172 int mb = (int) ((mem >> 20) & 0x3FF); 173 int kb = (int) ((mem >> 10) & 0x3FF); 174 int bytes = (int) (mem & 0x3FF); 175 StringBuffer sbuf = new StringBuffer(30); 176 if (gb > 0) { 177 sbuf.append(gb); 178 sbuf.append("GB "); 179 } 180 if ((mb > 0) || (gb > 0)) { 181 sbuf.append(mb); 182 sbuf.append("MB "); 183 } 184 if ((kb > 0) || (mb > 0) || (gb > 0)) { 185 sbuf.append(kb); 186 sbuf.append("KB "); 187 } 188 if ((bytes > 0) || (kb > 0) || (mb > 0) || (gb > 0)) { 189 sbuf.append(bytes); 190 sbuf.append("bytes "); 191 } 192 sbuf.append("("); 193 sbuf.append(mem); 194 sbuf.append("bytes)"); 195 return sbuf.toString(); 196 } 197 198 public final static void memDown(final Runtime r) { 199 long oldmem; 200 do { 201 oldmem = getUsedMem(r); 202 for (int i = 0; i < 10; i++) { 203 // Calling System.gc once is very unsafe 204 System.gc(); 205 try { 206 Thread.sleep(10); 207 } catch (InterruptedException ie) { 208 } 209 } 210 } while (getUsedMem(r) < oldmem); 211 } 212 }