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.IntConfOption; 22 import org.apache.hadoop.conf.Configuration; 23 24 import com.sun.management.GcInfo; 25 26 /** 27 * Tracks last k GC pauses and is able to tell how much time was spent doing 28 * GC since some point in time. Thread safe. 29 */ 30 public class GcTracker { 31 /** How many last gcs to keep */ 32 public static final IntConfOption LAST_GCS_TO_KEEP = 33 new IntConfOption("giraph.lastGcsToKeep", 100, 34 "How many last gcs to keep"); 35 36 /** Last k GCs which happened */ 37 private final GcInfo[] lastKGcs; 38 /** Next position to write gc to */ 39 private int positionInGcs = 0; 40 41 /** 42 * Constructor with default number of last gcs to keep 43 */ 44 public GcTracker() { 45 lastKGcs = new GcInfo[LAST_GCS_TO_KEEP.getDefaultValue()]; 46 } 47 48 /** 49 * Constructor with configuration 50 * 51 * @param conf Configuration 52 */ 53 public GcTracker(Configuration conf) { 54 lastKGcs = new GcInfo[LAST_GCS_TO_KEEP.get(conf)]; 55 } 56 57 /** 58 * Called to notify gc tracker that gc occurred 59 * 60 * @param gcInfo GC info 61 */ 62 public synchronized void gcOccurred(GcInfo gcInfo) { 63 lastKGcs[positionInGcs] = gcInfo; 64 positionInGcs++; 65 if (positionInGcs == lastKGcs.length) { 66 positionInGcs = 0; 67 } 68 } 69 70 /** 71 * Check how much time was spent doing gc since some timestamp 72 * 73 * @param timeSinceJvmStarted Timestamp to measure from, you can use 74 * ManagementFactory.getRuntimeMXBean().getUptime() to get it 75 * @return How much time was spent doing gc since that timestamp (if there 76 * were more gcs than we are keeping (LAST_GCS_TO_KEEP) then it will be 77 * partial result) 78 */ 79 public synchronized long gcTimeSpentSince(long timeSinceJvmStarted) { 80 long ret = 0; 81 int currentPosition = positionInGcs; 82 do { 83 currentPosition--; 84 if (currentPosition < 0) { 85 currentPosition = lastKGcs.length - 1; 86 } 87 // If there was no such GC or GC started before the timestamp given, 88 // stop iterating 89 if (lastKGcs[currentPosition] == null || 90 lastKGcs[currentPosition].getStartTime() < timeSinceJvmStarted) { 91 break; 92 } 93 ret += lastKGcs[currentPosition].getDuration(); 94 } while (currentPosition != positionInGcs); 95 return ret; 96 } 97 }