1/*2 * Licensed to the Apache Software Foundation (ASF) under one3 * or more contributor license agreements. See the NOTICE file4 * distributed with this work for additional information5 * regarding copyright ownership. The ASF licenses this file6 * to you under the Apache License, Version 2.0 (the7 * "License"); you may not use this file except in compliance8 * with the License. You may obtain a copy of the License at9 *10 * http://www.apache.org/licenses/LICENSE-2.011 *12 * Unless required by applicable law or agreed to in writing, software13 * 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 and16 * limitations under the License.17 */1819package org.apache.giraph.utils;
2021import org.apache.giraph.conf.GiraphConstants;
22import org.apache.giraph.conf.ImmutableClassesGiraphConfiguration;
23import org.apache.giraph.master.MasterObserver;
24import org.apache.giraph.metrics.AggregatedMetrics;
25import org.apache.giraph.partition.PartitionStats;
26import org.apache.giraph.worker.WorkerObserver;
27import org.apache.log4j.Logger;
2829import java.util.List;
3031/**32 * An observer for both worker and master that periodically dumps the memory33 * usage using jmap tool.34 */35publicclassJMapHistoDumperimplements MasterObserver, WorkerObserver {
36/** Logger */37privatestaticfinal Logger LOG = Logger.getLogger(JMapHistoDumper.class);
3839/** How many msec to sleep between calls */40privateint sleepMillis;
41/** How many lines of output to print */42privateint linesToPrint;
43/** Should only print live objects */44privateboolean liveObjectsOnly;
4546/** The jmap printing thread */47private Thread thread;
48/** Halt jmap thread */49privatevolatileboolean stop = false;
50/** Path to jmap*/51private String jmapPath;
5253 @Override
54publicvoid preLoad() {
55// This is called by both WorkerObserver and MasterObserver56 startJMapThread();
57 }
5859 @Override
60publicvoid postSave() {
61// This is called by both WorkerObserver and MasterObserver62 joinJMapThread();
63 }
6465 @Override
66publicvoid preApplication() {
67 }
6869 @Override
70publicvoid postApplication() {
71 }
7273/**74 * Join the jmap thread75 */76privatevoid joinJMapThread() {
77 stop = true;
78try {
79 thread.interrupt();
80 thread.join(sleepMillis + 5000);
81 } catch (InterruptedException e) {
82 LOG.error("Failed to join jmap thread");
83 }
84 }
8586/**87 * Start the jmap thread88 */89publicvoid startJMapThread() {
90 stop = false;
91 thread = ThreadUtils.startThread(new Runnable() {
92 @Override
93publicvoid run() {
94while (!stop) {
95 JMap.heapHistogramDump(linesToPrint, liveObjectsOnly, jmapPath);
96 ThreadUtils.trySleep(sleepMillis);
97 }
98 }
99 }, "jmap-dumper");
100 }
101102 @Override
103publicvoid preSuperstep(long superstep) { }
104105 @Override
106publicvoid postSuperstep(long superstep) { }
107108 @Override
109publicvoid superstepMetricsUpdate(long superstep,
110AggregatedMetrics aggregatedMetrics,
111 List<PartitionStats> partitionStatsList) { }
112113 @Override
114publicvoid applicationFailed(Exception e) { }
115116 @Override
117publicvoid setConf(ImmutableClassesGiraphConfiguration configuration) {
118 sleepMillis = GiraphConstants.JMAP_SLEEP_MILLIS.get(configuration);
119 linesToPrint = GiraphConstants.JMAP_PRINT_LINES.get(configuration);
120 liveObjectsOnly = GiraphConstants.JMAP_LIVE_ONLY.get(configuration);
121 jmapPath = GiraphConstants.JMAP_PATH.get(configuration);
122 }
123124 @Override
125publicImmutableClassesGiraphConfiguration getConf() {
126returnnull;
127 }
128 }