package cyrille.performances; import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import java.io.DataOutputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.net.ServerSocket; import java.net.Socket; /** * This hacky class is used to trigger a heap dump on a running VM. To use, start this program like * this: * * <pre> * * java NetDumper /tmp/foo.hprof 7000 * * * </pre> * * This will cause it to listen to a ServerSocket on port 7000. Next, invoke the program you want a * heap dump for, like this: * * <pre> * * java -Xhprof:net=localhost:7000,format=b com.random.MyProgram * * </pre> * * It will connect to NetDumper. Whenever you press return in the NetDumper window, it will request * a heap dump, and write it to /tmp/foo.hprof. */ public class NetDumper implements Runnable { // // Data members // private InputStream in; private OutputStream out; private int identifierSize; private byte[] buf = new byte[16 * 1024]; public NetDumper(InputStream in, OutputStream out) { this.in = in; this.out = out; } public void run() { try { for (;;) { int read = this.in.read(this.buf); if (read == -1) { System.out.println("EOF seen, terminating."); this.out.close(); System.exit(0); } this.out.write(this.buf, 0, read); } } catch (IOException ex) { ex.printStackTrace(); System.exit(1); } } private static void usage() { System.out.println("Usage: java NetDumper <file> <port>"); System.exit(1); } public static void main(String args[]) { if (args.length != 2) { usage(); } try { String file = args[0]; int port = Integer.parseInt(args[1], 10); ServerSocket ss = new ServerSocket(port); System.out.println("Listenening on port " + port); Socket s = ss.accept(); InputStream in = new BufferedInputStream(s.getInputStream()); System.out.println("Writing to file " + file); OutputStream out = new BufferedOutputStream(new FileOutputStream(file)); NetDumper d = new NetDumper(in, out); (new Thread(d)).start(); DataOutputStream toVM = new DataOutputStream(s.getOutputStream()); for (;;) { System.out.print("Press return to request heap dump..."); System.out.flush(); for (;;) { int ch = System.in.read(); if (ch == -1) { System.out.println("EOF on stdin, aborting."); System.exit(1); } if (ch == '\n') { break; } } System.out.println("Requesting heap dump."); toVM.writeByte(2); // HPROF_CMD_DUMP_HEAP toVM.writeInt(1); // seq_num toVM.writeInt(0); // length toVM.flush(); } } catch (Exception ex) { ex.printStackTrace(); } } }