Author: jbellis
Date: Thu Mar 4 20:11:30 2010
New Revision: 919150
URL: http://svn.apache.org/viewvc?rev=919150&view=rev
Log:
log GC activity. patch by Brandon Williams and jbellis for CASSANDRA-813
Added:
incubator/cassandra/branches/cassandra-0.6/src/java/org/apache/cassandra/service/GCInspector.java
Modified:
incubator/cassandra/branches/cassandra-0.6/CHANGES.txt
incubator/cassandra/branches/cassandra-0.6/src/java/org/apache/cassandra/service/StorageService.java
Modified: incubator/cassandra/branches/cassandra-0.6/CHANGES.txt
URL:
http://svn.apache.org/viewvc/incubator/cassandra/branches/cassandra-0.6/CHANGES.txt?rev=919150&r1=919149&r2=919150&view=diff
==============================================================================
--- incubator/cassandra/branches/cassandra-0.6/CHANGES.txt (original)
+++ incubator/cassandra/branches/cassandra-0.6/CHANGES.txt Thu Mar 4 20:11:30
2010
@@ -10,6 +10,7 @@
large rows get big enough to threaten node stability, and -x option to
be able to remove them with sstable2json if the warning is unheeded
until it's too late (CASSANDRA-843)
+ * Add logging of GC activity (CASSANDRA-813)
0.6.0-beta1/beta2
Added:
incubator/cassandra/branches/cassandra-0.6/src/java/org/apache/cassandra/service/GCInspector.java
URL:
http://svn.apache.org/viewvc/incubator/cassandra/branches/cassandra-0.6/src/java/org/apache/cassandra/service/GCInspector.java?rev=919150&view=auto
==============================================================================
---
incubator/cassandra/branches/cassandra-0.6/src/java/org/apache/cassandra/service/GCInspector.java
(added)
+++
incubator/cassandra/branches/cassandra-0.6/src/java/org/apache/cassandra/service/GCInspector.java
Thu Mar 4 20:11:30 2010
@@ -0,0 +1,94 @@
+package org.apache.cassandra.service;
+
+import org.apache.log4j.Logger;
+
+import java.util.*;
+import java.util.concurrent.ExecutorService;
+import org.apache.cassandra.concurrent.JMXEnabledThreadPoolExecutor;
+import org.apache.cassandra.utils.WrappedRunnable;
+
+import com.sun.management.GarbageCollectorMXBean;
+import com.sun.management.GcInfo;
+import java.lang.management.MemoryUsage;
+import java.lang.management.ManagementFactory;
+import javax.management.MBeanServer;
+import javax.management.ObjectName;
+
+public class GCInspector
+{
+ public static final GCInspector instance = new GCInspector();
+
+ private static final Logger logger = Logger.getLogger(GCInspector.class);
+ final static long INTERVAL_IN_MS = 10 * 1000;
+ final static long MIN_DURATION = 200;
+
+ private HashMap<String, Long> gctimes = new HashMap<String, Long>();
+
+ List<GarbageCollectorMXBean> beans = new
ArrayList<GarbageCollectorMXBean>();
+
+ public GCInspector()
+ {
+ MBeanServer server = ManagementFactory.getPlatformMBeanServer();
+ try
+ {
+ ObjectName gcName = new
ObjectName(ManagementFactory.GARBAGE_COLLECTOR_MXBEAN_DOMAIN_TYPE + ",*");
+ for (ObjectName name : server.queryNames(gcName, null))
+ {
+ GarbageCollectorMXBean gc =
ManagementFactory.newPlatformMXBeanProxy(server, name.getCanonicalName(),
GarbageCollectorMXBean.class);
+ beans.add(gc);
+ }
+ }
+ catch (Exception e)
+ {
+ throw new RuntimeException(e);
+ }
+ }
+
+ public void start()
+ {
+ TimerTask t = new TimerTask()
+ {
+ public void run()
+ {
+ logIntervalGCStats();
+ }
+ };
+ new Timer("GC inspection").schedule(t, INTERVAL_IN_MS, INTERVAL_IN_MS);
+ }
+
+ private void logIntervalGCStats()
+ {
+ for (GarbageCollectorMXBean gc : beans)
+ {
+ GcInfo gci = gc.getLastGcInfo();
+ if (gci == null)
+ continue;
+
+ Long previous = gctimes.get(gc.getName());
+ if (previous != null && previous == gc.getCollectionTime())
+ continue;
+ gctimes.put(gc.getName(), gc.getCollectionTime());
+
+ long previousMemoryUsed = 0;
+ long memoryUsed = 0;
+ long memoryMax = 0;
+ for (Map.Entry<String, MemoryUsage> entry :
gci.getMemoryUsageBeforeGc().entrySet())
+ {
+ previousMemoryUsed += entry.getValue().getUsed();
+ }
+ for (Map.Entry<String, MemoryUsage> entry :
gci.getMemoryUsageAfterGc().entrySet())
+ {
+ MemoryUsage mu = entry.getValue();
+ memoryUsed += mu.getUsed();
+ memoryMax += mu.getMax();
+ }
+
+ String st = String.format("GC for %s: %s ms, %s reclaimed leaving
%s used; max is %s",
+ gc.getName(), gci.getDuration(),
previousMemoryUsed - memoryUsed, memoryUsed, memoryMax);
+ if (gci.getDuration() > MIN_DURATION)
+ logger.info(st);
+ else if (logger.isDebugEnabled())
+ logger.debug(st);
+ }
+ }
+}
Modified:
incubator/cassandra/branches/cassandra-0.6/src/java/org/apache/cassandra/service/StorageService.java
URL:
http://svn.apache.org/viewvc/incubator/cassandra/branches/cassandra-0.6/src/java/org/apache/cassandra/service/StorageService.java?rev=919150&r1=919149&r2=919150&view=diff
==============================================================================
---
incubator/cassandra/branches/cassandra-0.6/src/java/org/apache/cassandra/service/StorageService.java
(original)
+++
incubator/cassandra/branches/cassandra-0.6/src/java/org/apache/cassandra/service/StorageService.java
Thu Mar 4 20:11:30 2010
@@ -302,6 +302,7 @@
isClientMode = false;
storageMetadata_ = SystemTable.initMetadata();
DatabaseDescriptor.createAllDirectories();
+ GCInspector.instance.start();
logger_.info("Starting up server gossip");
MessagingService.instance.listen(FBUtilities.getLocalAddress());