6995781: Native Memory Tracking (Phase 1)

7151532: DCmd for hotspot native memory tracking

Implementation of native memory tracking phase 1, which tracks VM native memory usage, and related DCmd

Reviewed-by: acorn, coleenp, fparain
This commit is contained in:
Zhengyu Gu 2012-06-28 17:03:16 -04:00
parent 8e42425c92
commit a39b17624a
315 changed files with 7245 additions and 1477 deletions

View file

@ -40,7 +40,7 @@
// must be shrunk. Adjusting the boundary between the generations
// is called for in this class.
class AdjoiningGenerations : public CHeapObj {
class AdjoiningGenerations : public CHeapObj<mtGC> {
friend class VMStructs;
private:
// The young generation and old generation, respectively

View file

@ -116,7 +116,7 @@ GCTaskQueue* GCTaskQueue::create() {
}
GCTaskQueue* GCTaskQueue::create_on_c_heap() {
GCTaskQueue* result = new(ResourceObj::C_HEAP) GCTaskQueue(true);
GCTaskQueue* result = new(ResourceObj::C_HEAP, mtGC) GCTaskQueue(true);
if (TraceGCTaskQueue) {
tty->print_cr("GCTaskQueue::create_on_c_heap()"
" returns " INTPTR_FORMAT,
@ -403,19 +403,19 @@ void GCTaskManager::initialize() {
_queue = SynchronizedGCTaskQueue::create(unsynchronized_queue, lock());
_noop_task = NoopGCTask::create_on_c_heap();
_idle_inactive_task = WaitForBarrierGCTask::create_on_c_heap();
_resource_flag = NEW_C_HEAP_ARRAY(bool, workers());
_resource_flag = NEW_C_HEAP_ARRAY(bool, workers(), mtGC);
{
// Set up worker threads.
// Distribute the workers among the available processors,
// unless we were told not to, or if the os doesn't want to.
uint* processor_assignment = NEW_C_HEAP_ARRAY(uint, workers());
uint* processor_assignment = NEW_C_HEAP_ARRAY(uint, workers(), mtGC);
if (!BindGCTaskThreadsToCPUs ||
!os::distribute_processes(workers(), processor_assignment)) {
for (uint a = 0; a < workers(); a += 1) {
processor_assignment[a] = sentinel_worker();
}
}
_thread = NEW_C_HEAP_ARRAY(GCTaskThread*, workers());
_thread = NEW_C_HEAP_ARRAY(GCTaskThread*, workers(), mtGC);
for (uint t = 0; t < workers(); t += 1) {
set_thread(t, GCTaskThread::create(this, t, processor_assignment[t]));
}
@ -426,7 +426,7 @@ void GCTaskManager::initialize() {
}
tty->cr();
}
FREE_C_HEAP_ARRAY(uint, processor_assignment);
FREE_C_HEAP_ARRAY(uint, processor_assignment, mtGC);
}
reset_busy_workers();
set_unblocked();
@ -455,11 +455,11 @@ GCTaskManager::~GCTaskManager() {
GCTaskThread::destroy(thread(i));
set_thread(i, NULL);
}
FREE_C_HEAP_ARRAY(GCTaskThread*, _thread);
FREE_C_HEAP_ARRAY(GCTaskThread*, _thread, mtGC);
_thread = NULL;
}
if (_resource_flag != NULL) {
FREE_C_HEAP_ARRAY(bool, _resource_flag);
FREE_C_HEAP_ARRAY(bool, _resource_flag, mtGC);
_resource_flag = NULL;
}
if (queue() != NULL) {
@ -817,7 +817,7 @@ NoopGCTask* NoopGCTask::create() {
}
NoopGCTask* NoopGCTask::create_on_c_heap() {
NoopGCTask* result = new(ResourceObj::C_HEAP) NoopGCTask(true);
NoopGCTask* result = new(ResourceObj::C_HEAP, mtGC) NoopGCTask(true);
return result;
}
@ -848,7 +848,7 @@ IdleGCTask* IdleGCTask::create() {
}
IdleGCTask* IdleGCTask::create_on_c_heap() {
IdleGCTask* result = new(ResourceObj::C_HEAP) IdleGCTask(true);
IdleGCTask* result = new(ResourceObj::C_HEAP, mtGC) IdleGCTask(true);
assert(UseDynamicNumberOfGCThreads,
"Should only be used with dynamic GC thread");
return result;
@ -984,7 +984,7 @@ WaitForBarrierGCTask* WaitForBarrierGCTask::create() {
WaitForBarrierGCTask* WaitForBarrierGCTask::create_on_c_heap() {
WaitForBarrierGCTask* result =
new (ResourceObj::C_HEAP) WaitForBarrierGCTask(true);
new (ResourceObj::C_HEAP, mtGC) WaitForBarrierGCTask(true);
return result;
}
@ -1114,7 +1114,7 @@ Monitor* MonitorSupply::reserve() {
// Lazy initialization.
if (freelist() == NULL) {
_freelist =
new(ResourceObj::C_HEAP) GrowableArray<Monitor*>(ParallelGCThreads,
new(ResourceObj::C_HEAP, mtGC) GrowableArray<Monitor*>(ParallelGCThreads,
true);
}
if (! freelist()->is_empty()) {

View file

@ -216,7 +216,7 @@ protected:
// A GCTaskQueue that can be synchronized.
// This "has-a" GCTaskQueue and a mutex to do the exclusion.
class SynchronizedGCTaskQueue : public CHeapObj {
class SynchronizedGCTaskQueue : public CHeapObj<mtGC> {
private:
// Instance state.
GCTaskQueue* _unsynchronized_queue; // Has-a unsynchronized queue.
@ -278,7 +278,7 @@ protected:
// This is an abstract base class for getting notifications
// when a GCTaskManager is done.
class NotifyDoneClosure : public CHeapObj {
class NotifyDoneClosure : public CHeapObj<mtGC> {
public:
// The notification callback method.
virtual void notify(GCTaskManager* manager) = 0;
@ -355,7 +355,7 @@ protected:
// held in the GCTaskThread** _thread array in GCTaskManager.
class GCTaskManager : public CHeapObj {
class GCTaskManager : public CHeapObj<mtGC> {
friend class ParCompactionManager;
friend class PSParallelCompact;
friend class PSScavenge;

View file

@ -46,7 +46,7 @@ GCTaskThread::GCTaskThread(GCTaskManager* manager,
vm_exit_out_of_memory(0, "Cannot create GC thread. Out of system resources.");
if (PrintGCTaskTimeStamps) {
_time_stamps = NEW_C_HEAP_ARRAY(GCTaskTimeStamp, GCTaskTimeStampEntries );
_time_stamps = NEW_C_HEAP_ARRAY(GCTaskTimeStamp, GCTaskTimeStampEntries, mtGC);
guarantee(_time_stamps != NULL, "Sanity");
}
@ -56,7 +56,7 @@ GCTaskThread::GCTaskThread(GCTaskManager* manager,
GCTaskThread::~GCTaskThread() {
if (_time_stamps != NULL) {
FREE_C_HEAP_ARRAY(GCTaskTimeStamp, _time_stamps);
FREE_C_HEAP_ARRAY(GCTaskTimeStamp, _time_stamps, mtGC);
}
}

View file

@ -90,7 +90,7 @@ protected:
void set_is_working(bool v) { _is_working = v; }
};
class GCTaskTimeStamp : public CHeapObj
class GCTaskTimeStamp : public CHeapObj<mtGC>
{
private:
jlong _entry_time;

View file

@ -28,6 +28,7 @@
#include "memory/cardTableModRefBS.hpp"
#include "oops/oop.inline.hpp"
#include "runtime/java.hpp"
#include "services/memTracker.hpp"
void ObjectStartArray::initialize(MemRegion reserved_region) {
// We're based on the assumption that we use the same
@ -50,6 +51,7 @@ void ObjectStartArray::initialize(MemRegion reserved_region) {
if (!backing_store.is_reserved()) {
vm_exit_during_initialization("Could not reserve space for ObjectStartArray");
}
MemTracker::record_virtual_memory_type((address)backing_store.base(), mtGC);
// We do not commit any memory initially
if (!_virtual_space.initialize(backing_store, 0)) {
@ -57,10 +59,14 @@ void ObjectStartArray::initialize(MemRegion reserved_region) {
}
_raw_base = (jbyte*)_virtual_space.low_boundary();
if (_raw_base == NULL) {
vm_exit_during_initialization("Could not get raw_base address");
}
MemTracker::record_virtual_memory_type((address)_raw_base, mtGC);
_offset_base = _raw_base - (size_t(reserved_region.start()) >> block_shift);
_covered_region.set_start(reserved_region.start());

View file

@ -35,7 +35,7 @@
// covered region.
//
class ObjectStartArray : public CHeapObj {
class ObjectStartArray : public CHeapObj<mtGC> {
friend class VerifyObjectStartArrayClosure;
private:

View file

@ -29,6 +29,7 @@
#include "oops/oop.inline.hpp"
#include "runtime/os.hpp"
#include "utilities/bitMap.inline.hpp"
#include "services/memTracker.hpp"
#ifdef TARGET_OS_FAMILY_linux
# include "os_linux.inline.hpp"
#endif
@ -61,6 +62,9 @@ ParMarkBitMap::initialize(MemRegion covered_region)
ReservedSpace rs(bytes, rs_align, rs_align > 0);
os::trace_page_sizes("par bitmap", raw_bytes, raw_bytes, page_sz,
rs.base(), rs.size());
MemTracker::record_virtual_memory_type((address)rs.base(), mtGC);
_virtual_space = new PSVirtualSpace(rs, page_sz);
if (_virtual_space != NULL && _virtual_space->expand_by(bytes)) {
_region_start = covered_region.start();

View file

@ -32,7 +32,7 @@
class oopDesc;
class ParMarkBitMapClosure;
class ParMarkBitMap: public CHeapObj
class ParMarkBitMap: public CHeapObj<mtGC>
{
public:
typedef BitMap::idx_t idx_t;

View file

@ -40,6 +40,7 @@
#include "runtime/handles.inline.hpp"
#include "runtime/java.hpp"
#include "runtime/vmThread.hpp"
#include "services/memTracker.hpp"
#include "utilities/vmError.hpp"
PSYoungGen* ParallelScavengeHeap::_young_gen = NULL;
@ -161,6 +162,8 @@ jint ParallelScavengeHeap::initialize() {
}
}
MemTracker::record_virtual_memory_type((address)heap_rs.base(), mtJavaHeap);
os::trace_page_sizes("ps perm", pg_min_size, pg_max_size, pg_page_sz,
heap_rs.base(), pg_max_size);
os::trace_page_sizes("ps main", og_min_size + yg_min_size,

View file

@ -81,14 +81,14 @@ void ParCompactionManager::initialize(ParMarkBitMap* mbm) {
uint parallel_gc_threads = PSParallelCompact::gc_task_manager()->workers();
assert(_manager_array == NULL, "Attempt to initialize twice");
_manager_array = NEW_C_HEAP_ARRAY(ParCompactionManager*, parallel_gc_threads+1 );
_manager_array = NEW_C_HEAP_ARRAY(ParCompactionManager*, parallel_gc_threads+1, mtGC);
guarantee(_manager_array != NULL, "Could not allocate manager_array");
_region_list = NEW_C_HEAP_ARRAY(RegionTaskQueue*,
parallel_gc_threads+1);
parallel_gc_threads+1, mtGC);
guarantee(_region_list != NULL, "Could not initialize promotion manager");
_recycled_stack_index = NEW_C_HEAP_ARRAY(uint, parallel_gc_threads);
_recycled_stack_index = NEW_C_HEAP_ARRAY(uint, parallel_gc_threads, mtGC);
// parallel_gc-threads + 1 to be consistent with the number of
// compaction managers.

View file

@ -41,7 +41,7 @@ class ObjectStartArray;
class ParallelCompactData;
class ParMarkBitMap;
class ParCompactionManager : public CHeapObj {
class ParCompactionManager : public CHeapObj<mtGC> {
friend class ParallelTaskTerminator;
friend class ParMarkBitMap;
friend class PSParallelCompact;
@ -66,8 +66,8 @@ class ParCompactionManager : public CHeapObj {
private:
// 32-bit: 4K * 8 = 32KiB; 64-bit: 8K * 16 = 128KiB
#define QUEUE_SIZE (1 << NOT_LP64(12) LP64_ONLY(13))
typedef OverflowTaskQueue<ObjArrayTask, QUEUE_SIZE> ObjArrayTaskQueue;
typedef GenericTaskQueueSet<ObjArrayTaskQueue> ObjArrayTaskQueueSet;
typedef OverflowTaskQueue<ObjArrayTask, mtGC, QUEUE_SIZE> ObjArrayTaskQueue;
typedef GenericTaskQueueSet<ObjArrayTaskQueue, mtGC> ObjArrayTaskQueueSet;
#undef QUEUE_SIZE
static ParCompactionManager** _manager_array;
@ -78,7 +78,7 @@ class ParCompactionManager : public CHeapObj {
static PSOldGen* _old_gen;
private:
OverflowTaskQueue<oop> _marking_stack;
OverflowTaskQueue<oop, mtGC> _marking_stack;
ObjArrayTaskQueue _objarray_stack;
// Is there a way to reuse the _marking_stack for the
@ -110,8 +110,8 @@ private:
// popped. If -1, there has not been any entry popped.
static int _recycled_bottom;
Stack<Klass*> _revisit_klass_stack;
Stack<DataLayout*> _revisit_mdo_stack;
Stack<Klass*, mtGC> _revisit_klass_stack;
Stack<DataLayout*, mtGC> _revisit_mdo_stack;
static ParMarkBitMap* _mark_bitmap;
@ -126,7 +126,7 @@ private:
protected:
// Array of tasks. Needed by the ParallelTaskTerminator.
static RegionTaskQueueSet* region_array() { return _region_array; }
OverflowTaskQueue<oop>* marking_stack() { return &_marking_stack; }
OverflowTaskQueue<oop, mtGC>* marking_stack() { return &_marking_stack; }
// Pushes onto the marking stack. If the marking stack is full,
// pushes onto the overflow stack.
@ -175,8 +175,8 @@ private:
bool should_update();
bool should_copy();
Stack<Klass*>* revisit_klass_stack() { return &_revisit_klass_stack; }
Stack<DataLayout*>* revisit_mdo_stack() { return &_revisit_mdo_stack; }
Stack<Klass*, mtGC>* revisit_klass_stack() { return &_revisit_klass_stack; }
Stack<DataLayout*, mtGC>* revisit_mdo_stack() { return &_revisit_mdo_stack; }
// Save for later processing. Must not fail.
inline void push(oop obj) { _marking_stack.push(obj); }

View file

@ -40,7 +40,7 @@ PSGenerationCounters::PSGenerationCounters(const char* name,
const char* cns = PerfDataManager::name_space("generation", ordinal);
_name_space = NEW_C_HEAP_ARRAY(char, strlen(cns)+1);
_name_space = NEW_C_HEAP_ARRAY(char, strlen(cns)+1, mtGC);
strcpy(_name_space, cns);
const char* cname = PerfDataManager::counter_name(_name_space, "name");

View file

@ -34,7 +34,7 @@
class ObjectStartArray;
class PSMarkSweepDecorator: public CHeapObj {
class PSMarkSweepDecorator: public CHeapObj<mtGC> {
private:
static PSMarkSweepDecorator* _destination_decorator;

View file

@ -34,7 +34,7 @@
class PSMarkSweepDecorator;
class PSOldGen : public CHeapObj {
class PSOldGen : public CHeapObj<mtGC> {
friend class VMStructs;
friend class PSPromotionManager; // Uses the cas_allocate methods
friend class ParallelScavengeHeap;

View file

@ -53,6 +53,7 @@
#include "runtime/vmThread.hpp"
#include "services/management.hpp"
#include "services/memoryService.hpp"
#include "services/memTracker.hpp"
#include "utilities/events.hpp"
#include "utilities/stack.inline.hpp"
@ -405,6 +406,9 @@ ParallelCompactData::create_vspace(size_t count, size_t element_size)
ReservedSpace rs(bytes, rs_align, rs_align > 0);
os::trace_page_sizes("par compact", raw_bytes, raw_bytes, page_sz, rs.base(),
rs.size());
MemTracker::record_virtual_memory_type((address)rs.base(), mtGC);
PSVirtualSpace* vspace = new PSVirtualSpace(rs, page_sz);
if (vspace != 0) {
if (vspace->expand_by(bytes)) {
@ -2732,7 +2736,7 @@ PSParallelCompact::follow_weak_klass_links() {
for (uint i = 0; i < ParallelGCThreads + 1; i++) {
ParCompactionManager* cm = ParCompactionManager::manager_array(i);
KeepAliveClosure keep_alive_closure(cm);
Stack<Klass*>* const rks = cm->revisit_klass_stack();
Stack<Klass*, mtGC>* const rks = cm->revisit_klass_stack();
if (PrintRevisitStats) {
gclog_or_tty->print_cr("Revisit klass stack[%u] length = " SIZE_FORMAT,
i, rks->size());
@ -2765,7 +2769,7 @@ void PSParallelCompact::follow_mdo_weak_refs() {
}
for (uint i = 0; i < ParallelGCThreads + 1; i++) {
ParCompactionManager* cm = ParCompactionManager::manager_array(i);
Stack<DataLayout*>* rms = cm->revisit_mdo_stack();
Stack<DataLayout*, mtGC>* rms = cm->revisit_mdo_stack();
if (PrintRevisitStats) {
gclog_or_tty->print_cr("Revisit MDO stack[%u] size = " SIZE_FORMAT,
i, rms->size());

View file

@ -36,7 +36,7 @@
class ObjectStartArray;
class PSPromotionLAB : public CHeapObj {
class PSPromotionLAB : public CHeapObj<mtGC> {
protected:
static size_t filler_header_size;

View file

@ -45,7 +45,7 @@ void PSPromotionManager::initialize() {
_young_space = heap->young_gen()->to_space();
assert(_manager_array == NULL, "Attempt to initialize twice");
_manager_array = NEW_C_HEAP_ARRAY(PSPromotionManager*, ParallelGCThreads+1 );
_manager_array = NEW_C_HEAP_ARRAY(PSPromotionManager*, ParallelGCThreads+1, mtGC);
guarantee(_manager_array != NULL, "Could not initialize promotion manager");
_stack_array_depth = new OopStarTaskQueueSet(ParallelGCThreads);

View file

@ -49,7 +49,7 @@ class MutableSpace;
class PSOldGen;
class ParCompactionManager;
class PSPromotionManager : public CHeapObj {
class PSPromotionManager : public CHeapObj<mtGC> {
friend class PSScavenge;
friend class PSRefProcTaskExecutor;
private:
@ -77,7 +77,7 @@ class PSPromotionManager : public CHeapObj {
bool _old_gen_is_full;
OopStarTaskQueue _claimed_stack_depth;
OverflowTaskQueue<oop> _claimed_stack_breadth;
OverflowTaskQueue<oop, mtGC> _claimed_stack_breadth;
bool _totally_drain;
uint _target_stack_size;

View file

@ -62,8 +62,8 @@ bool PSScavenge::_survivor_overflow = false;
int PSScavenge::_tenuring_threshold = 0;
HeapWord* PSScavenge::_young_generation_boundary = NULL;
elapsedTimer PSScavenge::_accumulated_time;
Stack<markOop> PSScavenge::_preserved_mark_stack;
Stack<oop> PSScavenge::_preserved_oop_stack;
Stack<markOop, mtGC> PSScavenge::_preserved_mark_stack;
Stack<oop, mtGC> PSScavenge::_preserved_oop_stack;
CollectorCounters* PSScavenge::_counters = NULL;
bool PSScavenge::_promotion_failed = false;

View file

@ -71,8 +71,8 @@ class PSScavenge: AllStatic {
static HeapWord* _young_generation_boundary; // The lowest address possible for the young_gen.
// This is used to decide if an oop should be scavenged,
// cards should be marked, etc.
static Stack<markOop> _preserved_mark_stack; // List of marks to be restored after failed promotion
static Stack<oop> _preserved_oop_stack; // List of oops that need their mark restored.
static Stack<markOop, mtGC> _preserved_mark_stack; // List of marks to be restored after failed promotion
static Stack<oop, mtGC> _preserved_oop_stack; // List of oops that need their mark restored.
static CollectorCounters* _counters; // collector performance counters
static bool _promotion_failed;

View file

@ -32,7 +32,7 @@
// VirtualSpace is data structure for committing a previously reserved address
// range in smaller chunks.
class PSVirtualSpace : public CHeapObj {
class PSVirtualSpace : public CHeapObj<mtGC> {
friend class VMStructs;
protected:
// The space is committed/uncommited in chunks of size _alignment. The

View file

@ -33,7 +33,7 @@
class PSMarkSweepDecorator;
class PSYoungGen : public CHeapObj {
class PSYoungGen : public CHeapObj<mtGC> {
friend class VMStructs;
friend class ParallelScavengeHeap;
friend class AdjoiningGenerations;