View Javadoc

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 org.apache.giraph.conf.GiraphConstants;
22  import org.apache.giraph.conf.ImmutableClassesGiraphConfiguration;
23  import org.apache.giraph.master.MasterObserver;
24  import org.apache.giraph.metrics.AggregatedMetrics;
25  import org.apache.giraph.partition.PartitionStats;
26  import org.apache.giraph.worker.WorkerObserver;
27  import org.apache.log4j.Logger;
28  
29  import java.util.List;
30  
31  /**
32   * An observer for both worker and master that periodically dumps the memory
33   * usage using jmap tool.
34   */
35  public class JMapHistoDumper implements MasterObserver, WorkerObserver {
36    /** Logger */
37    private static final Logger LOG = Logger.getLogger(JMapHistoDumper.class);
38  
39    /** How many msec to sleep between calls */
40    private int sleepMillis;
41    /** How many lines of output to print */
42    private int linesToPrint;
43    /** Should only print live objects */
44    private boolean liveObjectsOnly;
45  
46    /** The jmap printing thread */
47    private Thread thread;
48    /** Halt jmap thread */
49    private volatile boolean stop = false;
50  
51    @Override
52    public void preLoad() {
53      // This is called by both WorkerObserver and MasterObserver
54      startJMapThread();
55    }
56  
57    @Override
58    public void postSave() {
59      // This is called by both WorkerObserver and MasterObserver
60      joinJMapThread();
61    }
62  
63    @Override
64    public void preApplication() {
65    }
66  
67    @Override
68    public void postApplication() {
69    }
70  
71    /**
72     * Join the jmap thread
73     */
74    private void joinJMapThread() {
75      stop = true;
76      try {
77        thread.interrupt();
78        thread.join(sleepMillis + 5000);
79      } catch (InterruptedException e) {
80        LOG.error("Failed to join jmap thread");
81      }
82    }
83  
84    /**
85     * Start the jmap thread
86     */
87    public void startJMapThread() {
88      stop = false;
89      thread = ThreadUtils.startThread(new Runnable() {
90        @Override
91        public void run() {
92          while (!stop) {
93            JMap.heapHistogramDump(linesToPrint, liveObjectsOnly);
94            ThreadUtils.trySleep(sleepMillis);
95          }
96        }
97      }, "jmap-dumper");
98    }
99  
100   @Override
101   public void preSuperstep(long superstep) { }
102 
103   @Override
104   public void postSuperstep(long superstep) { }
105 
106   @Override
107   public void superstepMetricsUpdate(long superstep,
108       AggregatedMetrics aggregatedMetrics,
109       List<PartitionStats> partitionStatsList) { }
110 
111   @Override
112   public void applicationFailed(Exception e) { }
113 
114   @Override
115   public void setConf(ImmutableClassesGiraphConfiguration configuration) {
116     sleepMillis = GiraphConstants.JMAP_SLEEP_MILLIS.get(configuration);
117     linesToPrint = GiraphConstants.JMAP_PRINT_LINES.get(configuration);
118     liveObjectsOnly = GiraphConstants.JMAP_LIVE_ONLY.get(configuration);
119   }
120 
121   @Override
122   public ImmutableClassesGiraphConfiguration getConf() {
123     return null;
124   }
125 }