comparison src/share/vm/services/memTrackWorker.cpp @ 7464:ecd24264898b

8005048: NMT: #loaded classes needs to just show the # defined classes Summary: Count number of instance classes so that it matches class metadata size Reviewed-by: coleenp, acorn
author zgu
date Tue, 08 Jan 2013 14:04:25 -0500
parents 33143ee07800
children 4102b59539ce
comparison
equal deleted inserted replaced
7396:4a2ed49abd51 7464:ecd24264898b
27 #include "services/memTracker.hpp" 27 #include "services/memTracker.hpp"
28 #include "services/memTrackWorker.hpp" 28 #include "services/memTrackWorker.hpp"
29 #include "utilities/decoder.hpp" 29 #include "utilities/decoder.hpp"
30 #include "utilities/vmError.hpp" 30 #include "utilities/vmError.hpp"
31 31
32
33 void GenerationData::reset() {
34 _number_of_classes = 0;
35 while (_recorder_list != NULL) {
36 MemRecorder* tmp = _recorder_list;
37 _recorder_list = _recorder_list->next();
38 MemTracker::release_thread_recorder(tmp);
39 }
40 }
41
32 MemTrackWorker::MemTrackWorker() { 42 MemTrackWorker::MemTrackWorker() {
33 // create thread uses cgc thread type for now. We should revisit 43 // create thread uses cgc thread type for now. We should revisit
34 // the option, or create new thread type. 44 // the option, or create new thread type.
35 _has_error = !os::create_thread(this, os::cgc_thread); 45 _has_error = !os::create_thread(this, os::cgc_thread);
36 set_name("MemTrackWorker", 0); 46 set_name("MemTrackWorker", 0);
37 47
38 // initial generation circuit buffer 48 // initial generation circuit buffer
39 if (!has_error()) { 49 if (!has_error()) {
40 _head = _tail = 0; 50 _head = _tail = 0;
41 for(int index = 0; index < MAX_GENERATIONS; index ++) { 51 for(int index = 0; index < MAX_GENERATIONS; index ++) {
42 _gen[index] = NULL; 52 ::new ((void*)&_gen[index]) GenerationData();
43 } 53 }
44 } 54 }
45 NOT_PRODUCT(_sync_point_count = 0;) 55 NOT_PRODUCT(_sync_point_count = 0;)
46 NOT_PRODUCT(_merge_count = 0;) 56 NOT_PRODUCT(_merge_count = 0;)
47 NOT_PRODUCT(_last_gen_in_use = 0;) 57 NOT_PRODUCT(_last_gen_in_use = 0;)
48 } 58 }
49 59
50 MemTrackWorker::~MemTrackWorker() { 60 MemTrackWorker::~MemTrackWorker() {
51 for (int index = 0; index < MAX_GENERATIONS; index ++) { 61 for (int index = 0; index < MAX_GENERATIONS; index ++) {
52 MemRecorder* rc = _gen[index]; 62 _gen[index].reset();
53 if (rc != NULL) {
54 delete rc;
55 }
56 } 63 }
57 } 64 }
58 65
59 void* MemTrackWorker::operator new(size_t size) { 66 void* MemTrackWorker::operator new(size_t size) {
60 assert(false, "use nothrow version"); 67 assert(false, "use nothrow version");
88 while (!MemTracker::shutdown_in_progress()) { 95 while (!MemTracker::shutdown_in_progress()) {
89 NOT_PRODUCT(_last_gen_in_use = generations_in_use();) 96 NOT_PRODUCT(_last_gen_in_use = generations_in_use();)
90 { 97 {
91 // take a recorder from earliest generation in buffer 98 // take a recorder from earliest generation in buffer
92 ThreadCritical tc; 99 ThreadCritical tc;
93 rec = _gen[_head]; 100 rec = _gen[_head].next_recorder();
94 if (rec != NULL) {
95 _gen[_head] = rec->next();
96 }
97 assert(count_recorder(_gen[_head]) <= MemRecorder::_instance_count,
98 "infinite loop after dequeue");
99 } 101 }
100 if (rec != NULL) { 102 if (rec != NULL) {
101 // merge the recorder into staging area 103 // merge the recorder into staging area
102 if (!snapshot->merge(rec)) { 104 if (!snapshot->merge(rec)) {
103 MemTracker::shutdown(MemTracker::NMT_out_of_memory); 105 MemTracker::shutdown(MemTracker::NMT_out_of_memory);
107 MemTracker::release_thread_recorder(rec); 109 MemTracker::release_thread_recorder(rec);
108 } else { 110 } else {
109 // no more recorder to merge, promote staging area 111 // no more recorder to merge, promote staging area
110 // to snapshot 112 // to snapshot
111 if (_head != _tail) { 113 if (_head != _tail) {
114 long number_of_classes;
112 { 115 {
113 ThreadCritical tc; 116 ThreadCritical tc;
114 if (_gen[_head] != NULL || _head == _tail) { 117 if (_gen[_head].has_more_recorder() || _head == _tail) {
115 continue; 118 continue;
116 } 119 }
120 number_of_classes = _gen[_head].number_of_classes();
121 _gen[_head].reset();
122
117 // done with this generation, increment _head pointer 123 // done with this generation, increment _head pointer
118 _head = (_head + 1) % MAX_GENERATIONS; 124 _head = (_head + 1) % MAX_GENERATIONS;
119 } 125 }
120 // promote this generation data to snapshot 126 // promote this generation data to snapshot
121 if (!snapshot->promote()) { 127 if (!snapshot->promote(number_of_classes)) {
122 // failed to promote, means out of memory 128 // failed to promote, means out of memory
123 MemTracker::shutdown(MemTracker::NMT_out_of_memory); 129 MemTracker::shutdown(MemTracker::NMT_out_of_memory);
124 } 130 }
125 } else { 131 } else {
126 snapshot->wait(1000); 132 snapshot->wait(1000);
127 ThreadCritical tc; 133 ThreadCritical tc;
128 // check if more data arrived 134 // check if more data arrived
129 if (_gen[_head] == NULL) { 135 if (!_gen[_head].has_more_recorder()) {
130 _gen[_head] = MemTracker::get_pending_recorders(); 136 _gen[_head].add_recorders(MemTracker::get_pending_recorders());
131 } 137 }
132 } 138 }
133 } 139 }
134 } 140 }
135 assert(MemTracker::shutdown_in_progress(), "just check"); 141 assert(MemTracker::shutdown_in_progress(), "just check");
145 // 151 //
146 // Following tasks are performed: 152 // Following tasks are performed:
147 // 1. add all recorders in pending queue to current generation 153 // 1. add all recorders in pending queue to current generation
148 // 2. increase generation 154 // 2. increase generation
149 155
150 void MemTrackWorker::at_sync_point(MemRecorder* rec) { 156 void MemTrackWorker::at_sync_point(MemRecorder* rec, int number_of_classes) {
151 NOT_PRODUCT(_sync_point_count ++;) 157 NOT_PRODUCT(_sync_point_count ++;)
152 assert(count_recorder(rec) <= MemRecorder::_instance_count, 158 assert(count_recorder(rec) <= MemRecorder::_instance_count,
153 "pending queue has infinite loop"); 159 "pending queue has infinite loop");
154 160
155 bool out_of_generation_buffer = false; 161 bool out_of_generation_buffer = false;
156 // check shutdown state inside ThreadCritical 162 // check shutdown state inside ThreadCritical
157 if (MemTracker::shutdown_in_progress()) return; 163 if (MemTracker::shutdown_in_progress()) return;
164
165 _gen[_tail].set_number_of_classes(number_of_classes);
158 // append the recorders to the end of the generation 166 // append the recorders to the end of the generation
159 if( rec != NULL) { 167 _gen[_tail].add_recorders(rec);
160 MemRecorder* cur_head = _gen[_tail]; 168 assert(count_recorder(_gen[_tail].peek()) <= MemRecorder::_instance_count,
161 if (cur_head == NULL) {
162 _gen[_tail] = rec;
163 } else {
164 while (cur_head->next() != NULL) {
165 cur_head = cur_head->next();
166 }
167 cur_head->set_next(rec);
168 }
169 }
170 assert(count_recorder(rec) <= MemRecorder::_instance_count,
171 "after add to current generation has infinite loop"); 169 "after add to current generation has infinite loop");
172 // we have collected all recorders for this generation. If there is data, 170 // we have collected all recorders for this generation. If there is data,
173 // we need to increment _tail to start a new generation. 171 // we need to increment _tail to start a new generation.
174 if (_gen[_tail] != NULL || _head == _tail) { 172 if (_gen[_tail].has_more_recorder() || _head == _tail) {
175 _tail = (_tail + 1) % MAX_GENERATIONS; 173 _tail = (_tail + 1) % MAX_GENERATIONS;
176 out_of_generation_buffer = (_tail == _head); 174 out_of_generation_buffer = (_tail == _head);
177 } 175 }
178 176
179 if (out_of_generation_buffer) { 177 if (out_of_generation_buffer) {
192 } 190 }
193 191
194 int MemTrackWorker::count_pending_recorders() const { 192 int MemTrackWorker::count_pending_recorders() const {
195 int count = 0; 193 int count = 0;
196 for (int index = 0; index < MAX_GENERATIONS; index ++) { 194 for (int index = 0; index < MAX_GENERATIONS; index ++) {
197 MemRecorder* head = _gen[index]; 195 MemRecorder* head = _gen[index].peek();
198 if (head != NULL) { 196 if (head != NULL) {
199 count += count_recorder(head); 197 count += count_recorder(head);
200 } 198 }
201 } 199 }
202 return count; 200 return count;