diff -r 4a2ed49abd51 -r ecd24264898b src/share/vm/services/memTrackWorker.cpp --- a/src/share/vm/services/memTrackWorker.cpp Fri Dec 07 10:55:16 2012 -0800 +++ b/src/share/vm/services/memTrackWorker.cpp Tue Jan 08 14:04:25 2013 -0500 @@ -29,6 +29,16 @@ #include "utilities/decoder.hpp" #include "utilities/vmError.hpp" + +void GenerationData::reset() { + _number_of_classes = 0; + while (_recorder_list != NULL) { + MemRecorder* tmp = _recorder_list; + _recorder_list = _recorder_list->next(); + MemTracker::release_thread_recorder(tmp); + } +} + MemTrackWorker::MemTrackWorker() { // create thread uses cgc thread type for now. We should revisit // the option, or create new thread type. @@ -39,7 +49,7 @@ if (!has_error()) { _head = _tail = 0; for(int index = 0; index < MAX_GENERATIONS; index ++) { - _gen[index] = NULL; + ::new ((void*)&_gen[index]) GenerationData(); } } NOT_PRODUCT(_sync_point_count = 0;) @@ -49,10 +59,7 @@ MemTrackWorker::~MemTrackWorker() { for (int index = 0; index < MAX_GENERATIONS; index ++) { - MemRecorder* rc = _gen[index]; - if (rc != NULL) { - delete rc; - } + _gen[index].reset(); } } @@ -90,12 +97,7 @@ { // take a recorder from earliest generation in buffer ThreadCritical tc; - rec = _gen[_head]; - if (rec != NULL) { - _gen[_head] = rec->next(); - } - assert(count_recorder(_gen[_head]) <= MemRecorder::_instance_count, - "infinite loop after dequeue"); + rec = _gen[_head].next_recorder(); } if (rec != NULL) { // merge the recorder into staging area @@ -109,16 +111,20 @@ // no more recorder to merge, promote staging area // to snapshot if (_head != _tail) { + long number_of_classes; { ThreadCritical tc; - if (_gen[_head] != NULL || _head == _tail) { + if (_gen[_head].has_more_recorder() || _head == _tail) { continue; } + number_of_classes = _gen[_head].number_of_classes(); + _gen[_head].reset(); + // done with this generation, increment _head pointer _head = (_head + 1) % MAX_GENERATIONS; } // promote this generation data to snapshot - if (!snapshot->promote()) { + if (!snapshot->promote(number_of_classes)) { // failed to promote, means out of memory MemTracker::shutdown(MemTracker::NMT_out_of_memory); } @@ -126,8 +132,8 @@ snapshot->wait(1000); ThreadCritical tc; // check if more data arrived - if (_gen[_head] == NULL) { - _gen[_head] = MemTracker::get_pending_recorders(); + if (!_gen[_head].has_more_recorder()) { + _gen[_head].add_recorders(MemTracker::get_pending_recorders()); } } } @@ -147,7 +153,7 @@ // 1. add all recorders in pending queue to current generation // 2. increase generation -void MemTrackWorker::at_sync_point(MemRecorder* rec) { +void MemTrackWorker::at_sync_point(MemRecorder* rec, int number_of_classes) { NOT_PRODUCT(_sync_point_count ++;) assert(count_recorder(rec) <= MemRecorder::_instance_count, "pending queue has infinite loop"); @@ -155,23 +161,15 @@ bool out_of_generation_buffer = false; // check shutdown state inside ThreadCritical if (MemTracker::shutdown_in_progress()) return; + + _gen[_tail].set_number_of_classes(number_of_classes); // append the recorders to the end of the generation - if( rec != NULL) { - MemRecorder* cur_head = _gen[_tail]; - if (cur_head == NULL) { - _gen[_tail] = rec; - } else { - while (cur_head->next() != NULL) { - cur_head = cur_head->next(); - } - cur_head->set_next(rec); - } - } - assert(count_recorder(rec) <= MemRecorder::_instance_count, + _gen[_tail].add_recorders(rec); + assert(count_recorder(_gen[_tail].peek()) <= MemRecorder::_instance_count, "after add to current generation has infinite loop"); // we have collected all recorders for this generation. If there is data, // we need to increment _tail to start a new generation. - if (_gen[_tail] != NULL || _head == _tail) { + if (_gen[_tail].has_more_recorder() || _head == _tail) { _tail = (_tail + 1) % MAX_GENERATIONS; out_of_generation_buffer = (_tail == _head); } @@ -194,7 +192,7 @@ int MemTrackWorker::count_pending_recorders() const { int count = 0; for (int index = 0; index < MAX_GENERATIONS; index ++) { - MemRecorder* head = _gen[index]; + MemRecorder* head = _gen[index].peek(); if (head != NULL) { count += count_recorder(head); }