1 /*
2 * Licensed to the Apache Software Foundation (ASF) under one
3 * or more contributor license agreements. See the NOTICE file
4 * distributed with this work for additional information
5 * regarding copyright ownership. The ASF licenses this file
6 * to you under the Apache License, Version 2.0 (the
7 * "License"); you may not use this file except in compliance
8 * with the License. You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
17 */
18
19 package org.apache.giraph.utils;
20
21 import java.io.BufferedReader;
22 import java.io.IOException;
23 import java.io.InputStreamReader;
24 import java.io.PrintStream;
25 import java.lang.management.ManagementFactory;
26 import java.nio.charset.Charset;
27 import java.util.Date;
28
29 /**
30 * Helper to run jmap and print the output
31 */
32 public class JMap {
33 /** Arguments to pass in to command */
34 public static final String ARGS = " -histo ";
35 /** This option will print out onlu live objects */
36 private static String LIVE_HISTO_OPTION = " -histo:live ";
37
38 /** Do not construct */
39 protected JMap() { }
40
41 /**
42 * Get the process ID of the current running process
43 *
44 * @return Integer process ID
45 */
46 public static int getProcessId() {
47 String processId = ManagementFactory.getRuntimeMXBean().getName();
48 if (processId.contains("@")) {
49 processId = processId.substring(0, processId.indexOf("@"));
50 }
51 return Integer.parseInt(processId);
52 }
53
54 /**
55 * Run jmap, print numLines of output from it to stderr.
56 *
57 * @param numLines Number of lines to print
58 * @param liveObjectsOnly Should we only print non GC-able objects?
59 * @param jmapPath Path to jmap binary
60 */
61 public static void heapHistogramDump(int numLines,
62 boolean liveObjectsOnly,
63 String jmapPath) {
64 heapHistogramDump(numLines, liveObjectsOnly, System.err, jmapPath);
65 }
66
67 /**
68 * Run jmap, print numLines of output from it to stderr.
69 *
70 * @param numLines Number of lines to print
71 * @param jmapPath Path to jmap binary
72 */
73 public static void heapHistogramDump(int numLines, String jmapPath) {
74 heapHistogramDump(numLines, System.err, jmapPath);
75 }
76
77 /**
78 * Run jmap, print numLines of output from it to stream passed in.
79 *
80 * @param numLines Number of lines to print
81 * @param printStream Stream to print to
82 * @param jmapPath Path to jmap binary
83 */
84 public static void heapHistogramDump(int numLines, PrintStream printStream,
85 String jmapPath) {
86 heapHistogramDump(numLines, false, printStream, jmapPath);
87 }
88
89 /**
90 * Run jmap, print numLines of output from it to stream passed in.
91 *
92 * @param numLines Number of lines to print
93 * @param liveObjectsOnly Should we only print non GC-able objects?
94 * @param printStream Stream to print to
95 * @param jmapPath Path to jmap binary
96 */
97 private static void heapHistogramDump(int numLines,
98 boolean liveObjectsOnly,
99 PrintStream printStream,
100 String jmapPath) {
101 try {
102 String args = liveObjectsOnly ? LIVE_HISTO_OPTION : ARGS;
103 Process p = Runtime.getRuntime().exec(jmapPath + args + getProcessId());
104 BufferedReader in = new BufferedReader(
105 new InputStreamReader(p.getInputStream(), Charset.defaultCharset()));
106 printStream.println("JMap " +
107 (liveObjectsOnly ? "histo:live" : "histo") +
108 " dump at " + new Date());
109 String line = in.readLine();
110 for (int i = 0; i < numLines && line != null; ++i) {
111 printStream.println("--\t" + line);
112 line = in.readLine();
113 }
114 in.close();
115 } catch (IOException e) {
116 e.printStackTrace();
117 }
118 }
119 }