From f38f61e58b84932536c3bc0f0a4693aeac8cd814 Mon Sep 17 00:00:00 2001 From: tonyp Date: Mon, 3 Oct 2011 19:04:14 -0400 Subject: [PATCH] 7097048: G1: extend the G1 SA changes to print per-heap space information Reviewed-by: brutisso, johnc --- .../gc_implementation/g1/G1CollectedHeap.java | 9 ++ .../g1/G1MonitoringSupport.java | 99 +++++++++++++++++++ .../sun/jvm/hotspot/tools/HeapSummary.java | 27 ++--- .../g1/g1MonitoringSupport.hpp | 2 + .../vm/gc_implementation/g1/vmStructs_g1.hpp | 11 +++ 5 files changed, 137 insertions(+), 11 deletions(-) create mode 100644 agent/src/share/classes/sun/jvm/hotspot/gc_implementation/g1/G1MonitoringSupport.java diff --git a/agent/src/share/classes/sun/jvm/hotspot/gc_implementation/g1/G1CollectedHeap.java b/agent/src/share/classes/sun/jvm/hotspot/gc_implementation/g1/G1CollectedHeap.java index dfdd51099..502d8e4ad 100644 --- a/agent/src/share/classes/sun/jvm/hotspot/gc_implementation/g1/G1CollectedHeap.java +++ b/agent/src/share/classes/sun/jvm/hotspot/gc_implementation/g1/G1CollectedHeap.java @@ -35,6 +35,7 @@ import sun.jvm.hotspot.memory.SharedHeap; import sun.jvm.hotspot.memory.SpaceClosure; import sun.jvm.hotspot.runtime.VM; import sun.jvm.hotspot.runtime.VMObjectFactory; +import sun.jvm.hotspot.types.AddressField; import sun.jvm.hotspot.types.CIntegerField; import sun.jvm.hotspot.types.Type; import sun.jvm.hotspot.types.TypeDataBase; @@ -48,6 +49,8 @@ public class G1CollectedHeap extends SharedHeap { static private long g1CommittedFieldOffset; // size_t _summary_bytes_used; static private CIntegerField summaryBytesUsedField; + // G1MonitoringSupport* _g1mm + static private AddressField g1mmField; static { VM.registerVMInitializedObserver(new Observer() { @@ -63,6 +66,7 @@ public class G1CollectedHeap extends SharedHeap { hrsFieldOffset = type.getField("_hrs").getOffset(); g1CommittedFieldOffset = type.getField("_g1_committed").getOffset(); summaryBytesUsedField = type.getCIntegerField("_summary_bytes_used"); + g1mmField = type.getAddressField("_g1mm"); } public long capacity() { @@ -85,6 +89,11 @@ public class G1CollectedHeap extends SharedHeap { hrsAddr); } + public G1MonitoringSupport g1mm() { + Address g1mmAddr = g1mmField.getValue(addr); + return (G1MonitoringSupport) VMObjectFactory.newObject(G1MonitoringSupport.class, g1mmAddr); + } + private Iterator heapRegionIterator() { return hrs().heapRegionIterator(); } diff --git a/agent/src/share/classes/sun/jvm/hotspot/gc_implementation/g1/G1MonitoringSupport.java b/agent/src/share/classes/sun/jvm/hotspot/gc_implementation/g1/G1MonitoringSupport.java new file mode 100644 index 000000000..7b03aed9c --- /dev/null +++ b/agent/src/share/classes/sun/jvm/hotspot/gc_implementation/g1/G1MonitoringSupport.java @@ -0,0 +1,99 @@ +/* + * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +package sun.jvm.hotspot.gc_implementation.g1; + +import java.util.Observable; +import java.util.Observer; + +import sun.jvm.hotspot.debugger.Address; +import sun.jvm.hotspot.runtime.VM; +import sun.jvm.hotspot.runtime.VMObject; +import sun.jvm.hotspot.types.CIntegerField; +import sun.jvm.hotspot.types.Type; +import sun.jvm.hotspot.types.TypeDataBase; + +// Mirror class for G1MonitoringSupport. + +public class G1MonitoringSupport extends VMObject { + // size_t _eden_committed; + static private CIntegerField edenCommittedField; + // size_t _eden_used; + static private CIntegerField edenUsedField; + // size_t _survivor_committed; + static private CIntegerField survivorCommittedField; + // size_t _survivor_used; + static private CIntegerField survivorUsedField; + // size_t _old_committed; + static private CIntegerField oldCommittedField; + // size_t _old_used; + static private CIntegerField oldUsedField; + + static { + VM.registerVMInitializedObserver(new Observer() { + public void update(Observable o, Object data) { + initialize(VM.getVM().getTypeDataBase()); + } + }); + } + + static private synchronized void initialize(TypeDataBase db) { + Type type = db.lookupType("G1MonitoringSupport"); + + edenCommittedField = type.getCIntegerField("_eden_committed"); + edenUsedField = type.getCIntegerField("_eden_used"); + survivorCommittedField = type.getCIntegerField("_survivor_committed"); + survivorUsedField = type.getCIntegerField("_survivor_used"); + oldCommittedField = type.getCIntegerField("_old_committed"); + oldUsedField = type.getCIntegerField("_old_used"); + } + + public long edenCommitted() { + return edenCommittedField.getValue(addr); + } + + public long edenUsed() { + return edenUsedField.getValue(addr); + } + + public long survivorCommitted() { + return survivorCommittedField.getValue(addr); + } + + public long survivorUsed() { + return survivorUsedField.getValue(addr); + } + + public long oldCommitted() { + return oldCommittedField.getValue(addr); + } + + public long oldUsed() { + return oldUsedField.getValue(addr); + } + + public G1MonitoringSupport(Address addr) { + super(addr); + } +} diff --git a/agent/src/share/classes/sun/jvm/hotspot/tools/HeapSummary.java b/agent/src/share/classes/sun/jvm/hotspot/tools/HeapSummary.java index 3be7f3da0..bbeab88a7 100644 --- a/agent/src/share/classes/sun/jvm/hotspot/tools/HeapSummary.java +++ b/agent/src/share/classes/sun/jvm/hotspot/tools/HeapSummary.java @@ -98,17 +98,12 @@ public class HeapSummary extends Tool { } } else if (sharedHeap instanceof G1CollectedHeap) { G1CollectedHeap g1h = (G1CollectedHeap) sharedHeap; - - System.out.println("Garbage-First (G1) Heap"); - long capacityBytes = g1h.capacity(); - long usedBytes = g1h.used(); - long freeBytes = capacityBytes - usedBytes; - printValMB("region size = ", HeapRegion.grainBytes()); - printValue("regions = ", g1h.n_regions()); - printValMB("capacity = ", capacityBytes); - printValMB("used = ", usedBytes); - printValMB("free = ", freeBytes); - System.out.println(alignment + (double) usedBytes * 100.0 / capacityBytes + "% used"); + G1MonitoringSupport g1mm = g1h.g1mm(); + System.out.println("G1 Young Generation"); + printG1Space("Eden Space:", g1mm.edenUsed(), g1mm.edenCommitted()); + printG1Space("From Space:", g1mm.survivorUsed(), g1mm.survivorCommitted()); + printG1Space("To Space:", 0, 0); + printG1Space("G1 Old Generation", g1mm.oldUsed(), g1mm.oldCommitted()); } else { throw new RuntimeException("unknown SharedHeap type : " + heap.getClass()); } @@ -217,6 +212,16 @@ public class HeapSummary extends Tool { System.out.println(alignment + (double)space.used() * 100.0 / space.capacity() + "% used"); } + private void printG1Space(String spaceName, long used, long capacity) { + long free = capacity - used; + System.out.println(spaceName); + printValMB("capacity = ", capacity); + printValMB("used = ", used); + printValMB("free = ", free); + double occPerc = (capacity > 0) ? (double) used * 100.0 / capacity : 0.0; + System.out.println(alignment + occPerc + "% used"); + } + private static final double FACTOR = 1024*1024; private void printValMB(String title, long value) { if (value < 0) { diff --git a/src/share/vm/gc_implementation/g1/g1MonitoringSupport.hpp b/src/share/vm/gc_implementation/g1/g1MonitoringSupport.hpp index aa142916b..3d124cefb 100644 --- a/src/share/vm/gc_implementation/g1/g1MonitoringSupport.hpp +++ b/src/share/vm/gc_implementation/g1/g1MonitoringSupport.hpp @@ -114,6 +114,8 @@ class G1CollectedHeap; // path as low-overhead as possible. class G1MonitoringSupport : public CHeapObj { + friend class VMStructs; + G1CollectedHeap* _g1h; // jstat performance counters diff --git a/src/share/vm/gc_implementation/g1/vmStructs_g1.hpp b/src/share/vm/gc_implementation/g1/vmStructs_g1.hpp index f85c76cee..1243a58a3 100644 --- a/src/share/vm/gc_implementation/g1/vmStructs_g1.hpp +++ b/src/share/vm/gc_implementation/g1/vmStructs_g1.hpp @@ -39,6 +39,14 @@ nonstatic_field(G1CollectedHeap, _hrs, HeapRegionSeq) \ nonstatic_field(G1CollectedHeap, _g1_committed, MemRegion) \ nonstatic_field(G1CollectedHeap, _summary_bytes_used, size_t) \ + nonstatic_field(G1CollectedHeap, _g1mm, G1MonitoringSupport*) \ + \ + nonstatic_field(G1MonitoringSupport, _eden_committed, size_t) \ + nonstatic_field(G1MonitoringSupport, _eden_used, size_t) \ + nonstatic_field(G1MonitoringSupport, _survivor_committed, size_t) \ + nonstatic_field(G1MonitoringSupport, _survivor_used, size_t) \ + nonstatic_field(G1MonitoringSupport, _old_committed, size_t) \ + nonstatic_field(G1MonitoringSupport, _old_used, size_t) \ #define VM_TYPES_G1(declare_type, declare_toplevel_type) \ @@ -47,8 +55,11 @@ \ declare_type(HeapRegion, ContiguousSpace) \ declare_toplevel_type(HeapRegionSeq) \ + declare_toplevel_type(G1MonitoringSupport) \ \ declare_toplevel_type(G1CollectedHeap*) \ declare_toplevel_type(HeapRegion*) \ + declare_toplevel_type(G1MonitoringSupport*) \ + #endif // SHARE_VM_GC_IMPLEMENTATION_G1_VMSTRUCTS_G1_HPP -- GitLab