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