67
68 void MemTrackWorker::start() {
69 os::start_thread(this);
70 }
71
72 /*
73 * Native memory tracking worker thread loop:
74 * 1. merge one generation of memory recorders to staging area
75 * 2. promote staging data to memory snapshot
76 *
77 * This thread can run through safepoint.
78 */
79
80 void MemTrackWorker::run() {
81 assert(MemTracker::is_on(), "native memory tracking is off");
82 this->initialize_thread_local_storage();
83 this->record_stack_base_and_size();
84 MemSnapshot* snapshot = MemTracker::get_snapshot();
85 assert(snapshot != NULL, "Worker should not be started");
86 MemRecorder* rec;
87
88 while (!MemTracker::shutdown_in_progress()) {
89 NOT_PRODUCT(_last_gen_in_use = generations_in_use();)
90 {
91 // take a recorder from earliest generation in buffer
92 ThreadCritical tc;
93 rec = _gen[_head];
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 }
100 if (rec != NULL) {
101 // merge the recorder into staging area
102 if (!snapshot->merge(rec)) {
103 MemTracker::shutdown(MemTracker::NMT_out_of_memory);
104 } else {
105 NOT_PRODUCT(_merge_count ++;)
106 }
107 MemTracker::release_thread_recorder(rec);
108 } else {
109 // no more recorder to merge, promote staging area
110 // to snapshot
111 if (_head != _tail) {
112 {
113 ThreadCritical tc;
114 if (_gen[_head] != NULL || _head == _tail) {
115 continue;
116 }
117 // done with this generation, increment _head pointer
118 _head = (_head + 1) % MAX_GENERATIONS;
119 }
120 // promote this generation data to snapshot
121 if (!snapshot->promote()) {
122 // failed to promote, means out of memory
123 MemTracker::shutdown(MemTracker::NMT_out_of_memory);
124 }
125 } else {
126 snapshot->wait(1000);
127 ThreadCritical tc;
128 // check if more data arrived
129 if (_gen[_head] == NULL) {
130 _gen[_head] = MemTracker::get_pending_recorders();
131 }
132 }
133 }
134 }
135 assert(MemTracker::shutdown_in_progress(), "just check");
136
137 // transits to final shutdown
138 MemTracker::final_shutdown();
139 }
140
141 // at synchronization point, where 'safepoint visible' Java threads are blocked
142 // at a safepoint, and the rest of threads are blocked on ThreadCritical lock.
143 // The caller MemTracker::sync() already takes ThreadCritical before calling this
144 // method.
145 //
|
67
68 void MemTrackWorker::start() {
69 os::start_thread(this);
70 }
71
72 /*
73 * Native memory tracking worker thread loop:
74 * 1. merge one generation of memory recorders to staging area
75 * 2. promote staging data to memory snapshot
76 *
77 * This thread can run through safepoint.
78 */
79
80 void MemTrackWorker::run() {
81 assert(MemTracker::is_on(), "native memory tracking is off");
82 this->initialize_thread_local_storage();
83 this->record_stack_base_and_size();
84 MemSnapshot* snapshot = MemTracker::get_snapshot();
85 assert(snapshot != NULL, "Worker should not be started");
86 MemRecorder* rec;
87 unsigned long processing_generation = 0;
88 bool worker_idle = false;
89
90 while (!MemTracker::shutdown_in_progress()) {
91 NOT_PRODUCT(_last_gen_in_use = generations_in_use();)
92 {
93 // take a recorder from earliest generation in buffer
94 ThreadCritical tc;
95 rec = _gen[_head];
96 if (rec != NULL) {
97 _gen[_head] = rec->next();
98 }
99 assert(count_recorder(_gen[_head]) <= MemRecorder::_instance_count,
100 "infinite loop after dequeue");
101 }
102 if (rec != NULL) {
103 if (rec->get_generation() != processing_generation || worker_idle) {
104 processing_generation = rec->get_generation();
105 worker_idle = false;
106 MemTracker::set_current_processing_generation(processing_generation);
107 }
108
109 // merge the recorder into staging area
110 if (!snapshot->merge(rec)) {
111 MemTracker::shutdown(MemTracker::NMT_out_of_memory);
112 } else {
113 NOT_PRODUCT(_merge_count ++;)
114 }
115 MemTracker::release_thread_recorder(rec);
116 } else {
117 // no more recorder to merge, promote staging area
118 // to snapshot
119 if (_head != _tail) {
120 {
121 ThreadCritical tc;
122 if (_gen[_head] != NULL || _head == _tail) {
123 continue;
124 }
125 // done with this generation, increment _head pointer
126 _head = (_head + 1) % MAX_GENERATIONS;
127 }
128 // promote this generation data to snapshot
129 if (!snapshot->promote()) {
130 // failed to promote, means out of memory
131 MemTracker::shutdown(MemTracker::NMT_out_of_memory);
132 }
133 } else {
134 // worker thread is idle
135 worker_idle = true;
136 MemTracker::report_worker_idle();
137 snapshot->wait(1000);
138 ThreadCritical tc;
139 // check if more data arrived
140 if (_gen[_head] == NULL) {
141 _gen[_head] = MemTracker::get_pending_recorders();
142 }
143 }
144 }
145 }
146 assert(MemTracker::shutdown_in_progress(), "just check");
147
148 // transits to final shutdown
149 MemTracker::final_shutdown();
150 }
151
152 // at synchronization point, where 'safepoint visible' Java threads are blocked
153 // at a safepoint, and the rest of threads are blocked on ThreadCritical lock.
154 // The caller MemTracker::sync() already takes ThreadCritical before calling this
155 // method.
156 //
|