180 total += lists[i].length(); |
181 total += lists[i].length(); |
181 } |
182 } |
182 return total; |
183 return total; |
183 } |
184 } |
184 |
185 |
|
186 static void log_ref_count(size_t count, bool doit) { |
|
187 if (doit) { |
|
188 gclog_or_tty->print(", " SIZE_FORMAT " refs", count); |
|
189 } |
|
190 } |
|
191 |
|
192 class GCRefTraceTime : public StackObj { |
|
193 GCTraceTimeImpl _gc_trace_time; |
|
194 public: |
|
195 GCRefTraceTime(const char* title, bool doit, GCTimer* timer, GCId gc_id, size_t count) : |
|
196 _gc_trace_time(title, doit, false, timer, gc_id) { |
|
197 log_ref_count(count, doit); |
|
198 } |
|
199 }; |
|
200 |
185 ReferenceProcessorStats ReferenceProcessor::process_discovered_references( |
201 ReferenceProcessorStats ReferenceProcessor::process_discovered_references( |
186 BoolObjectClosure* is_alive, |
202 BoolObjectClosure* is_alive, |
187 OopClosure* keep_alive, |
203 OopClosure* keep_alive, |
188 VoidClosure* complete_gc, |
204 VoidClosure* complete_gc, |
189 AbstractRefProcTaskExecutor* task_executor, |
205 AbstractRefProcTaskExecutor* task_executor, |
204 |
220 |
205 _soft_ref_timestamp_clock = java_lang_ref_SoftReference::clock(); |
221 _soft_ref_timestamp_clock = java_lang_ref_SoftReference::clock(); |
206 |
222 |
207 bool trace_time = PrintGCDetails && PrintReferenceGC; |
223 bool trace_time = PrintGCDetails && PrintReferenceGC; |
208 |
224 |
|
225 // Include cleaners in phantom statistics. We expect Cleaner |
|
226 // references to be temporary, and don't want to deal with |
|
227 // possible incompatibilities arising from making it more visible. |
|
228 ReferenceProcessorStats stats( |
|
229 total_count(_discoveredSoftRefs), |
|
230 total_count(_discoveredWeakRefs), |
|
231 total_count(_discoveredFinalRefs), |
|
232 total_count(_discoveredPhantomRefs) + total_count(_discoveredCleanerRefs)); |
|
233 |
209 // Soft references |
234 // Soft references |
210 size_t soft_count = 0; |
|
211 { |
235 { |
212 GCTraceTime tt("SoftReference", trace_time, false, gc_timer, gc_id); |
236 GCRefTraceTime tt("SoftReference", trace_time, gc_timer, gc_id, stats.soft_count()); |
213 soft_count = |
237 process_discovered_reflist(_discoveredSoftRefs, _current_soft_ref_policy, true, |
214 process_discovered_reflist(_discoveredSoftRefs, _current_soft_ref_policy, true, |
238 is_alive, keep_alive, complete_gc, task_executor); |
215 is_alive, keep_alive, complete_gc, task_executor); |
|
216 } |
239 } |
217 |
240 |
218 update_soft_ref_master_clock(); |
241 update_soft_ref_master_clock(); |
219 |
242 |
220 // Weak references |
243 // Weak references |
221 size_t weak_count = 0; |
|
222 { |
244 { |
223 GCTraceTime tt("WeakReference", trace_time, false, gc_timer, gc_id); |
245 GCRefTraceTime tt("WeakReference", trace_time, gc_timer, gc_id, stats.weak_count()); |
224 weak_count = |
246 process_discovered_reflist(_discoveredWeakRefs, NULL, true, |
225 process_discovered_reflist(_discoveredWeakRefs, NULL, true, |
247 is_alive, keep_alive, complete_gc, task_executor); |
226 is_alive, keep_alive, complete_gc, task_executor); |
|
227 } |
248 } |
228 |
249 |
229 // Final references |
250 // Final references |
230 size_t final_count = 0; |
|
231 { |
251 { |
232 GCTraceTime tt("FinalReference", trace_time, false, gc_timer, gc_id); |
252 GCRefTraceTime tt("FinalReference", trace_time, gc_timer, gc_id, stats.final_count()); |
233 final_count = |
253 process_discovered_reflist(_discoveredFinalRefs, NULL, false, |
234 process_discovered_reflist(_discoveredFinalRefs, NULL, false, |
254 is_alive, keep_alive, complete_gc, task_executor); |
235 is_alive, keep_alive, complete_gc, task_executor); |
|
236 } |
255 } |
237 |
256 |
238 // Phantom references |
257 // Phantom references |
239 size_t phantom_count = 0; |
|
240 { |
258 { |
241 GCTraceTime tt("PhantomReference", trace_time, false, gc_timer, gc_id); |
259 GCRefTraceTime tt("PhantomReference", trace_time, gc_timer, gc_id, stats.phantom_count()); |
242 phantom_count = |
260 process_discovered_reflist(_discoveredPhantomRefs, NULL, false, |
243 process_discovered_reflist(_discoveredPhantomRefs, NULL, false, |
261 is_alive, keep_alive, complete_gc, task_executor); |
244 is_alive, keep_alive, complete_gc, task_executor); |
262 |
245 |
263 // Process cleaners, but include them in phantom timing. We expect |
246 // Process cleaners, but include them in phantom statistics. We expect |
|
247 // Cleaner references to be temporary, and don't want to deal with |
264 // Cleaner references to be temporary, and don't want to deal with |
248 // possible incompatibilities arising from making it more visible. |
265 // possible incompatibilities arising from making it more visible. |
249 phantom_count += |
266 process_discovered_reflist(_discoveredCleanerRefs, NULL, true, |
250 process_discovered_reflist(_discoveredCleanerRefs, NULL, true, |
|
251 is_alive, keep_alive, complete_gc, task_executor); |
267 is_alive, keep_alive, complete_gc, task_executor); |
252 } |
268 } |
253 |
269 |
254 // Weak global JNI references. It would make more sense (semantically) to |
270 // Weak global JNI references. It would make more sense (semantically) to |
255 // traverse these simultaneously with the regular weak references above, but |
271 // traverse these simultaneously with the regular weak references above, but |
256 // that is not how the JDK1.2 specification is. See #4126360. Native code can |
272 // that is not how the JDK1.2 specification is. See #4126360. Native code can |
257 // thus use JNI weak references to circumvent the phantom references and |
273 // thus use JNI weak references to circumvent the phantom references and |
258 // resurrect a "post-mortem" object. |
274 // resurrect a "post-mortem" object. |
259 { |
275 { |
260 GCTraceTime tt("JNI Weak Reference", trace_time, false, gc_timer, gc_id); |
276 GCTraceTime tt("JNI Weak Reference", trace_time, false, gc_timer, gc_id); |
|
277 NOT_PRODUCT(log_ref_count(count_jni_refs(), trace_time);) |
261 if (task_executor != NULL) { |
278 if (task_executor != NULL) { |
262 task_executor->set_single_threaded_mode(); |
279 task_executor->set_single_threaded_mode(); |
263 } |
280 } |
264 process_phaseJNI(is_alive, keep_alive, complete_gc); |
281 process_phaseJNI(is_alive, keep_alive, complete_gc); |
265 } |
282 } |
266 |
283 |
267 return ReferenceProcessorStats(soft_count, weak_count, final_count, phantom_count); |
284 return stats; |
268 } |
285 } |
269 |
286 |
270 #ifndef PRODUCT |
287 #ifndef PRODUCT |
271 // Calculate the number of jni handles. |
288 // Calculate the number of jni handles. |
272 uint ReferenceProcessor::count_jni_refs() { |
289 uint ReferenceProcessor::count_jni_refs() { |