Home | History | Annotate | Download | only in asm
      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 }