ClassPoolからgetして、
setNameで新しいクラス名を設定して、
toClassでClassオブジェクト作る。
package my; public interface SampleIF { String getSimpleClassName(); }
package my; public class Sample implements SampleIF { public String getSimpleClassName() { return this.getClass().getSimpleName(); } }
package my; public class Main { public static void main(String[] args) throws NotFoundException, CannotCompileException, InstantiationException, IllegalAccessException, InterruptedException, IOException { Sample sample = new Sample(); for (long i = 0; i < 200000000; ++i) { ClassPool cp = ClassPool.getDefault(); CtClass cc = cp.get(sample.getClass().getName()); String className = cc.getName(); String baseSimpleName = cc.getSimpleName(); cc.setName(className + i); SampleIF s = (SampleIF) cc.toClass().newInstance(); if ((baseSimpleName + i).equals(s.getSimpleClassName()) == false) { throw new RuntimeException( "expect:" + (baseSimpleName + i) + ", actual:" + s.getSimpleClassName()); } if (i % 10000 == 0) { System.err.println(i); } } } }
./bin/my/Main.class
./bin/my/SampleIF.class
./bin/my/Sample.class
./lib/javassist-3.4.ga.jar
って置いて、
java -XX:PermSize=1024m -Xmx4096m -Xms4096m -cp "./bin;lib/javassist-3.4.ga.jar" my.Main
とかやると、5分か10分ぐらいかけて64万個ものクラスを作った後、OutOfMemoryError: PermGen spaceで終わります。
-XX:PermSize=1024mの値をいじれば作れるクラスの数を増減させることができました。
(オプション指定しないと4万ぐらいで終わる。ここから逆算するとPermSizeのデフォルト値は64MBぐらいの模様?)