Source Code Cross Referenced for JMap.java in  » 6.0-JDK-Modules-sun » tools » sun » tools » jmap » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » 6.0 JDK Modules sun » tools » sun.tools.jmap 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*
002:         * Copyright 2005-2006 Sun Microsystems, Inc.  All Rights Reserved.
003:         * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
004:         *
005:         * This code is free software; you can redistribute it and/or modify it
006:         * under the terms of the GNU General Public License version 2 only, as
007:         * published by the Free Software Foundation.  Sun designates this
008:         * particular file as subject to the "Classpath" exception as provided
009:         * by Sun in the LICENSE file that accompanied this code.
010:         *
011:         * This code is distributed in the hope that it will be useful, but WITHOUT
012:         * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
013:         * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
014:         * version 2 for more details (a copy is included in the LICENSE file that
015:         * accompanied this code).
016:         *
017:         * You should have received a copy of the GNU General Public License version
018:         * 2 along with this work; if not, write to the Free Software Foundation,
019:         * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
020:         *
021:         * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
022:         * CA 95054 USA or visit www.sun.com if you need additional information or
023:         * have any questions.
024:         */
025:
026:        package sun.tools.jmap;
027:
028:        import java.lang.reflect.Method;
029:        import java.io.File;
030:        import java.io.IOException;
031:        import java.io.InputStream;
032:
033:        import com.sun.tools.attach.VirtualMachine;
034:        import com.sun.tools.attach.AttachNotSupportedException;
035:        import sun.tools.attach.HotSpotVirtualMachine;
036:
037:        /*
038:         * This class is the main class for the JMap utility. It parses its arguments 
039:         * and decides if the command should be satisifed using the VM attach mechanism 
040:         * or an SA tool. At this time the only option that uses the VM attach mechanism 
041:         * is the -dump option to get a heap dump of a running application. All other 
042:         * options are mapped to SA tools. 
043:         */
044:        public class JMap {
045:
046:            // Options handled by the attach mechanism
047:            private static String HISTO_OPTION = "-histo";
048:            private static String LIVE_HISTO_OPTION = "-histo:live";
049:            private static String DUMP_OPTION_PREFIX = "-dump:";
050:
051:            // These options imply the use of a SA tool
052:            private static String SA_TOOL_OPTIONS = "-heap|-heap:format=b|-permstat|-finalizerinfo";
053:
054:            // The -F (force) option is currently not passed through to SA 
055:            private static String FORCE_SA_OPTION = "-F";
056:
057:            // Default option (if nothing provided)
058:            private static String DEFAULT_OPTION = "-heap";
059:
060:            public static void main(String[] args) throws Exception {
061:                if (args.length == 0) {
062:                    usage(); // no arguments
063:                }
064:
065:                // used to indicate if we should use SA  
066:                boolean useSA = false;
067:
068:                // the chosen option (-heap, -dump:*, ... )
069:                String option = null;
070:
071:                // First iterate over the options (arguments starting with -).  There should be
072:                // one (but maybe two if -F is also used).
073:                int optionCount = 0;
074:                while (optionCount < args.length) {
075:                    String arg = args[optionCount];
076:                    if (!arg.startsWith("-")) {
077:                        break;
078:                    }
079:                    if (arg.equals(FORCE_SA_OPTION)) {
080:                        useSA = true;
081:                    } else {
082:                        if (option != null) {
083:                            usage(); // option already specified
084:                        }
085:                        option = arg;
086:                    }
087:                    optionCount++;
088:                }
089:
090:                // if no option provided then use default. 
091:                if (option == null) {
092:                    option = DEFAULT_OPTION;
093:                }
094:                if (option.matches(SA_TOOL_OPTIONS)) {
095:                    useSA = true;
096:                }
097:
098:                // Next we check the parameter count. For the SA tools there are
099:                // one or two parameters. For the built-in -dump option there is
100:                // only one parameter (the process-id)
101:                int paramCount = args.length - optionCount;
102:                if (paramCount == 0 || paramCount > 2) {
103:                    usage();
104:                }
105:
106:                if (optionCount == 0 || paramCount != 1) {
107:                    useSA = true;
108:                } else {
109:                    // the parameter for the -dump option is a process-id.
110:                    // If it doesn't parse to a number then it must be SA
111:                    // debug server                
112:                    if (!args[optionCount].matches("[0-9]+")) {
113:                        useSA = true;
114:                    }
115:                }
116:
117:                // at this point we know if we are executing an SA tool or a built-in
118:                // option.
119:
120:                if (useSA) {
121:                    // parameters (<pid> or <exe> <core>)
122:                    String params[] = new String[paramCount];
123:                    for (int i = optionCount; i < args.length; i++) {
124:                        params[i - optionCount] = args[i];
125:                    }
126:                    runTool(option, params);
127:
128:                } else {
129:                    String pid = args[1];
130:                    // Here we handle the built-in options 
131:                    // As more options are added we should create an abstract tool class and
132:                    // have a table to map the options
133:                    if (option.equals(HISTO_OPTION)) {
134:                        histo(pid, false);
135:                    } else if (option.equals(LIVE_HISTO_OPTION)) {
136:                        histo(pid, true);
137:                    } else if (option.startsWith(DUMP_OPTION_PREFIX)) {
138:                        dump(pid, option);
139:                    } else {
140:                        usage();
141:                    }
142:                }
143:            }
144:
145:            // Invoke SA tool  with the given arguments
146:            private static void runTool(String option, String args[])
147:                    throws Exception {
148:                String[][] tools = {
149:                        { "-heap", "sun.jvm.hotspot.tools.HeapSummary" },
150:                        { "-heap:format=b", "sun.jvm.hotspot.tools.HeapDumper" },
151:                        { "-histo", "sun.jvm.hotspot.tools.ObjectHistogram" },
152:                        { "-permstat", "sun.jvm.hotspot.tools.PermStat" },
153:                        { "-finalizerinfo",
154:                                "sun.jvm.hotspot.tools.FinalizerInfo" }, };
155:
156:                String tool = null;
157:
158:                // -dump option needs to be handled in a special way        
159:                if (option.startsWith(DUMP_OPTION_PREFIX)) {
160:                    // first check that the option can be parsed
161:                    String fn = parseDumpOptions(option);
162:                    if (fn == null)
163:                        usage();
164:
165:                    // tool for heap dumping
166:                    tool = "sun.jvm.hotspot.tools.HeapDumper";
167:
168:                    // HeapDumper -f <file>
169:                    args = prepend(fn, args);
170:                    args = prepend("-f", args);
171:                } else {
172:                    int i = 0;
173:                    while (i < tools.length) {
174:                        if (option.equals(tools[i][0])) {
175:                            tool = tools[i][1];
176:                            break;
177:                        }
178:                        i++;
179:                    }
180:                }
181:                if (tool == null) {
182:                    usage(); // no mapping to tool
183:                }
184:
185:                // Tool not available on this  platform.
186:                Class<?> c = loadClass(tool);
187:                if (c == null) {
188:                    usage();
189:                }
190:
191:                // invoke the main method with the arguments
192:                Class[] argTypes = { String[].class };
193:                Method m = c.getDeclaredMethod("main", argTypes);
194:
195:                Object[] invokeArgs = { args };
196:                m.invoke(null, invokeArgs);
197:            }
198:
199:            // loads the given class using the system class loader
200:            private static Class loadClass(String name) {
201:                //
202:                // We specify the system clas loader so as to cater for development 
203:                // environments where this class is on the boot class path but sa-jdi.jar 
204:                // is on the system class path. Once the JDK is deployed then both
205:                // tools.jar and sa-jdi.jar are on the system class path.
206:                //
207:                try {
208:                    return Class.forName(name, true, ClassLoader
209:                            .getSystemClassLoader());
210:                } catch (Exception x) {
211:                }
212:                return null;
213:            }
214:
215:            private static final String LIVE_OBJECTS_OPTION = "-live";
216:            private static final String ALL_OBJECTS_OPTION = "-all";
217:
218:            private static void histo(String pid, boolean live)
219:                    throws IOException {
220:                VirtualMachine vm = attach(pid);
221:                InputStream in = ((HotSpotVirtualMachine) vm)
222:                        .heapHisto(live ? LIVE_OBJECTS_OPTION
223:                                : ALL_OBJECTS_OPTION);
224:                drain(vm, in);
225:            }
226:
227:            private static void dump(String pid, String options)
228:                    throws IOException {
229:                // parse the options to get the dump filename
230:                String filename = parseDumpOptions(options);
231:                if (filename == null) {
232:                    usage(); // invalid options or no filename
233:                }
234:
235:                // get the canonical path - important to avoid just passing
236:                // a "heap.bin" and having the dump created in the target VM
237:                // working directory rather than the directory where jmap
238:                // is executed.
239:                filename = new File(filename).getCanonicalPath();
240:
241:                // dump live objects only or not
242:                boolean live = isDumpLiveObjects(options);
243:
244:                VirtualMachine vm = attach(pid);
245:                System.out.println("Dumping heap to " + filename + " ...");
246:                InputStream in = ((HotSpotVirtualMachine) vm).dumpHeap(
247:                        (Object) filename, (live ? LIVE_OBJECTS_OPTION
248:                                : ALL_OBJECTS_OPTION));
249:                drain(vm, in);
250:            }
251:
252:            // Parse the options to the -dump option. Valid options are format=b and
253:            // file=<file>. Returns <file> if provided. Returns null if <file> not
254:            // provided, or invalid option.
255:            private static String parseDumpOptions(String arg) {
256:                assert arg.startsWith(DUMP_OPTION_PREFIX);
257:
258:                String filename = null;
259:
260:                // options are separated by comma (,)
261:                String options[] = arg.substring(DUMP_OPTION_PREFIX.length())
262:                        .split(",");
263:
264:                for (int i = 0; i < options.length; i++) {
265:                    String option = options[i];
266:
267:                    if (option.equals("format=b")) {
268:                        // ignore format (not needed at this time)
269:                    } else if (option.equals("live")) {
270:                        // a valid suboption
271:                    } else {
272:
273:                        // file=<file> - check that <file> is specified
274:                        if (option.startsWith("file=")) {
275:                            filename = option.substring(5);
276:                            if (filename.length() == 0) {
277:                                return null;
278:                            }
279:                        } else {
280:                            return null; // option not recognized
281:                        }
282:                    }
283:                }
284:                return filename;
285:            }
286:
287:            private static boolean isDumpLiveObjects(String arg) {
288:                // options are separated by comma (,)
289:                String options[] = arg.substring(DUMP_OPTION_PREFIX.length())
290:                        .split(",");
291:                for (String suboption : options) {
292:                    if (suboption.equals("live")) {
293:                        return true;
294:                    }
295:                }
296:                return false;
297:            }
298:
299:            // Attach to <pid>, existing if we fail to attach
300:            private static VirtualMachine attach(String pid) {
301:                try {
302:                    return VirtualMachine.attach(pid);
303:                } catch (Exception x) {
304:                    String msg = x.getMessage();
305:                    if (msg != null) {
306:                        System.err.println(pid + ": " + msg);
307:                    } else {
308:                        x.printStackTrace();
309:                    }
310:                    if ((x instanceof  AttachNotSupportedException) && haveSA()) {
311:                        System.err
312:                                .println("The -F option can be used when the "
313:                                        + "target process is not responding");
314:                    }
315:                    System.exit(1);
316:                    return null; // keep compiler happy
317:                }
318:            }
319:
320:            // Read the stream from the target VM until EOF, then detach
321:            private static void drain(VirtualMachine vm, InputStream in)
322:                    throws IOException {
323:                // read to EOF and just print output
324:                byte b[] = new byte[256];
325:                int n;
326:                do {
327:                    n = in.read(b);
328:                    if (n > 0) {
329:                        String s = new String(b, 0, n, "UTF-8");
330:                        System.out.print(s);
331:                    }
332:                } while (n > 0);
333:                in.close();
334:                vm.detach();
335:            }
336:
337:            // return a new string array with arg as the first element
338:            private static String[] prepend(String arg, String args[]) {
339:                String[] newargs = new String[args.length + 1];
340:                newargs[0] = arg;
341:                System.arraycopy(args, 0, newargs, 1, args.length);
342:                return newargs;
343:            }
344:
345:            // returns true if SA is available
346:            private static boolean haveSA() {
347:                Class c = loadClass("sun.jvm.hotspot.tools.HeapSummary");
348:                return (c != null);
349:            }
350:
351:            // print usage message
352:            private static void usage() {
353:                System.out.println("Usage:");
354:                if (haveSA()) {
355:                    System.out.println("    jmap [option] <pid>");
356:                    System.out
357:                            .println("        (to connect to running process)");
358:                    System.out.println("    jmap [option] <executable <core>");
359:                    System.out.println("        (to connect to a core file)");
360:                    System.out
361:                            .println("    jmap [option] [server_id@]<remote server IP or hostname>");
362:                    System.out
363:                            .println("        (to connect to remote debug server)");
364:                    System.out.println("");
365:                    System.out.println("where <option> is one of:");
366:                    System.out
367:                            .println("    <none>               to print same info as Solaris pmap");
368:                    System.out
369:                            .println("    -heap                to print java heap summary");
370:                    System.out
371:                            .println("    -histo[:live]        to print histogram of java object heap; if the \"live\"");
372:                    System.out
373:                            .println("                         suboption is specified, only count live objects");
374:                    System.out
375:                            .println("    -permstat            to print permanent generation statistics");
376:                    System.out
377:                            .println("    -finalizerinfo       to print information on objects awaiting finalization");
378:                    System.out
379:                            .println("    -dump:<dump-options> to dump java heap in hprof binary format");
380:                    System.out
381:                            .println("                         dump-options:");
382:                    System.out
383:                            .println("                           live         dump only live objects; if not specified,");
384:                    System.out
385:                            .println("                                        all objects in the heap are dumped.");
386:                    System.out
387:                            .println("                           format=b     binary format");
388:                    System.out
389:                            .println("                           file=<file>  dump heap to <file>");
390:                    System.out
391:                            .println("                         Example: jmap -dump:live,format=b,file=heap.bin <pid>");
392:                    System.out
393:                            .println("    -F                   force. Use with -dump:<dump-options> <pid> or -histo");
394:                    System.out
395:                            .println("                         to force a heap dump or histogram when <pid> does not");
396:                    System.out
397:                            .println("                         respond. The \"live\" suboption is not supported");
398:                    System.out
399:                            .println("                         in this mode.");
400:                    System.out
401:                            .println("    -h | -help           to print this help message");
402:                    System.out
403:                            .println("    -J<flag>             to pass <flag> directly to the runtime system");
404:                } else {
405:                    System.out.println("    jmap -histo <pid>");
406:                    System.out
407:                            .println("      (to connect to running process and print histogram of java object heap");
408:                    System.out.println("    jmap -dump:<dump-options> <pid>");
409:                    System.out
410:                            .println("      (to connect to running process and dump java heap)");
411:                    System.out.println("");
412:                    System.out.println("    dump-options:");
413:                    System.out.println("      format=b     binary default");
414:                    System.out
415:                            .println("      file=<file>  dump heap to <file>");
416:                    System.out.println("");
417:                    System.out
418:                            .println("    Example:       jmap -dump:format=b,file=heap.bin <pid>");
419:                }
420:
421:                System.exit(1);
422:            }
423:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.