通过HotSpot的Serviceability Agent 导出JVM Class文件
public class DumpClassTest{ public static void main(String[] args){ while(true){ try{ Thread.sleep(1000); }catche(Exception e){} } }}
?2、编写DumpClass类,该类依赖
/home/tools/jdk1.6.0_43/lib/sa-jdi.jar
?
import java.io.BufferedOutputStream;import java.io.File;import java.io.FileOutputStream;import java.io.IOException;import java.io.OutputStream;import java.util.jar.JarEntry;import java.util.jar.JarOutputStream;import sun.jvm.hotspot.bugspot.BugSpotAgent;import sun.jvm.hotspot.memory.SystemDictionary;import sun.jvm.hotspot.oops.InstanceKlass;import sun.jvm.hotspot.oops.Klass;import sun.jvm.hotspot.runtime.VM;import sun.jvm.hotspot.tools.jcore.ClassWriter;public class DumpVMClass {private static JarOutputStream jarStream;//导出目录地址private static String outputDirectory = "/home/tools/jdk1.6.0_43/class/";public static void main(String[] args){BugSpotAgent agent = new BugSpotAgent();try {int pid = Integer.parseInt(args[0]);agent.attach(pid);boolean isJavaMode = agent.isJavaMode();if(isJavaMode){SystemDictionary dict = VM.getVM().getSystemDictionary();dict.classesDo(new SystemDictionary.ClassVisitor() { public void visit(Klass k) { if (!(k instanceof InstanceKlass)) return; try { DumpVMClass.dumpKlass((InstanceKlass)k); } catch (Exception e) { System.out.println(k.getName().asString()); e.printStackTrace(); } } });}} catch (Exception e) {e.printStackTrace();}finally{ agent.detach();}}private static void dumpKlass(InstanceKlass kls) { String klassName = kls.getName().asString(); klassName = klassName.replace('/', File.separatorChar); try { OutputStream os = null; if (DumpVMClass.jarStream != null) { DumpVMClass.jarStream.putNextEntry(new JarEntry(klassName + ".class")); os = DumpVMClass.jarStream; } else { int index = klassName.lastIndexOf(File.separatorChar); File dir = null; if (index != -1) { String dirName = klassName.substring(0, index); dir = new File(DumpVMClass.outputDirectory, dirName); } else { dir = new File(DumpVMClass.outputDirectory); } dir.mkdirs(); File f = new File(dir, klassName.substring(index + 1) + ".class"); f.createNewFile(); os = new BufferedOutputStream(new FileOutputStream(f)); } try { ClassWriter cw = new ClassWriter(kls, os); cw.write(); } finally { if (os != DumpVMClass.jarStream) os.close(); } } catch (IOException exp) { exp.printStackTrace(); } }}??
?3、先运行DumpClassTest:
[root@oem-ci3bcm02f1h bin]# javac DumpClassTest.java [root@oem-ci3bcm02f1h bin]# java DumpClassTest & [5] 14060[root@oem-ci3bcm02f1h bin]#?4、获得PID 14060 后运行 DumpVMClass:
?
[root@oem-ci3bcm02f1h bin]# javac -cp .:../lib/sa-jdi.jar DumpVMClass.java[root@oem-ci3bcm02f1h bin]# java -cp .:../lib/sa-jdi.jar DumpVMClass 14060[root@oem-ci3bcm02f1h bin]#
?
5、运行完就可以看到:
/home/tools/jdk1.6.0_43/class/ 目录下该JVM 14060进程 的class文件都被dump出来了。
?
注:
??? 以上DumpVMClass 代码大部分来自于sa-jdi.jar 的
sun.jvm.hotspot.tools.jcore.ClassDump
?