< prev index next >

src/share/vm/gc/shared/referenceProcessor.cpp

Print this page
rev 13139 : [mq]: heap7


  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  *
  23  */
  24 
  25 #include "precompiled.hpp"
  26 #include "classfile/javaClasses.inline.hpp"
  27 #include "classfile/systemDictionary.hpp"
  28 #include "gc/shared/collectedHeap.hpp"
  29 #include "gc/shared/collectedHeap.inline.hpp"
  30 #include "gc/shared/gcTimer.hpp"
  31 #include "gc/shared/gcTraceTime.inline.hpp"
  32 #include "gc/shared/referencePolicy.hpp"
  33 #include "gc/shared/referenceProcessor.inline.hpp"
  34 #include "logging/log.hpp"
  35 #include "memory/allocation.hpp"
  36 #include "memory/resourceArea.hpp"
  37 #include "oops/oop.inline.hpp"

  38 #include "runtime/java.hpp"
  39 #include "runtime/jniHandles.hpp"
  40 
  41 ReferencePolicy* ReferenceProcessor::_always_clear_soft_ref_policy = NULL;
  42 ReferencePolicy* ReferenceProcessor::_default_soft_ref_policy      = NULL;
  43 jlong            ReferenceProcessor::_soft_ref_timestamp_clock = 0;
  44 
  45 void referenceProcessor_init() {
  46   ReferenceProcessor::init_statics();
  47 }
  48 
  49 void ReferenceProcessor::init_statics() {
  50   // We need a monotonically non-decreasing time in ms but
  51   // os::javaTimeMillis() does not guarantee monotonicity.
  52   jlong now = os::javaTimeNanos() / NANOSECS_PER_MILLISEC;
  53 
  54   // Initialize the soft ref timestamp clock.
  55   _soft_ref_timestamp_clock = now;
  56   // Also update the soft ref clock in j.l.r.SoftReference
  57   java_lang_ref_SoftReference::set_clock(_soft_ref_timestamp_clock);


 240   // Phantom references
 241   {
 242     GCTraceTime(Debug, gc, ref) tt("PhantomReference", gc_timer);
 243     process_discovered_reflist(_discoveredPhantomRefs, NULL, true,
 244                                is_alive, keep_alive, complete_gc, task_executor);
 245   }
 246 
 247   // Weak global JNI references. It would make more sense (semantically) to
 248   // traverse these simultaneously with the regular weak references above, but
 249   // that is not how the JDK1.2 specification is. See #4126360. Native code can
 250   // thus use JNI weak references to circumvent the phantom references and
 251   // resurrect a "post-mortem" object.
 252   {
 253     GCTraceTime(Debug, gc, ref) tt("JNI Weak Reference", gc_timer);
 254     if (task_executor != NULL) {
 255       task_executor->set_single_threaded_mode();
 256     }
 257     process_phaseJNI(is_alive, keep_alive, complete_gc);
 258   }
 259 






 260   log_debug(gc, ref)("Ref Counts: Soft: " SIZE_FORMAT " Weak: " SIZE_FORMAT " Final: " SIZE_FORMAT " Phantom: " SIZE_FORMAT,
 261                      stats.soft_count(), stats.weak_count(), stats.final_count(), stats.phantom_count());
 262   log_develop_trace(gc, ref)("JNI Weak Reference count: " SIZE_FORMAT, count_jni_refs());

 263 
 264   return stats;
 265 }
 266 
 267 #ifndef PRODUCT
 268 // Calculate the number of jni handles.
 269 size_t ReferenceProcessor::count_jni_refs() {
 270   class CountHandleClosure: public OopClosure {
 271   private:
 272     size_t _count;
 273   public:
 274     CountHandleClosure(): _count(0) {}
 275     void do_oop(oop* unused)       { _count++; }
 276     void do_oop(narrowOop* unused) { ShouldNotReachHere(); }
 277     size_t count() { return _count; }
 278   };
 279   CountHandleClosure global_handle_count;
 280   JNIHandles::weak_oops_do(&global_handle_count);
 281   return global_handle_count.count();
 282 }
 283 #endif
 284 
 285 void ReferenceProcessor::process_phaseJNI(BoolObjectClosure* is_alive,
 286                                           OopClosure*        keep_alive,
 287                                           VoidClosure*       complete_gc) {
 288   JNIHandles::weak_oops_do(is_alive, keep_alive);
 289   complete_gc->do_void();
















 290 }
 291 
 292 void ReferenceProcessor::enqueue_discovered_references(AbstractRefProcTaskExecutor* task_executor) {
 293   // Enqueue references that are not made active again, and
 294   // clear the decks for the next collection (cycle).
 295   enqueue_discovered_reflists(task_executor);
 296 
 297   // Stop treating discovered references specially.
 298   disable_discovery();
 299 }
 300 
 301 void ReferenceProcessor::enqueue_discovered_reflist(DiscoveredList& refs_list) {
 302   // Given a list of refs linked through the "discovered" field
 303   // (java.lang.ref.Reference.discovered), self-loop their "next" field
 304   // thus distinguishing them from active References, then
 305   // prepend them to the pending list.
 306   //
 307   // The Java threads will see the Reference objects linked together through
 308   // the discovered field. Instead of trying to do the write barrier updates
 309   // in all places in the reference processor where we manipulate the discovered




  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  *
  23  */
  24 
  25 #include "precompiled.hpp"
  26 #include "classfile/javaClasses.inline.hpp"
  27 #include "classfile/systemDictionary.hpp"
  28 #include "gc/shared/collectedHeap.hpp"
  29 #include "gc/shared/collectedHeap.inline.hpp"
  30 #include "gc/shared/gcTimer.hpp"
  31 #include "gc/shared/gcTraceTime.inline.hpp"
  32 #include "gc/shared/referencePolicy.hpp"
  33 #include "gc/shared/referenceProcessor.inline.hpp"
  34 #include "logging/log.hpp"
  35 #include "memory/allocation.hpp"
  36 #include "memory/resourceArea.hpp"
  37 #include "oops/oop.inline.hpp"
  38 #include "runtime/heapMonitoring.hpp"
  39 #include "runtime/java.hpp"
  40 #include "runtime/jniHandles.hpp"
  41 
  42 ReferencePolicy* ReferenceProcessor::_always_clear_soft_ref_policy = NULL;
  43 ReferencePolicy* ReferenceProcessor::_default_soft_ref_policy      = NULL;
  44 jlong            ReferenceProcessor::_soft_ref_timestamp_clock = 0;
  45 
  46 void referenceProcessor_init() {
  47   ReferenceProcessor::init_statics();
  48 }
  49 
  50 void ReferenceProcessor::init_statics() {
  51   // We need a monotonically non-decreasing time in ms but
  52   // os::javaTimeMillis() does not guarantee monotonicity.
  53   jlong now = os::javaTimeNanos() / NANOSECS_PER_MILLISEC;
  54 
  55   // Initialize the soft ref timestamp clock.
  56   _soft_ref_timestamp_clock = now;
  57   // Also update the soft ref clock in j.l.r.SoftReference
  58   java_lang_ref_SoftReference::set_clock(_soft_ref_timestamp_clock);


 241   // Phantom references
 242   {
 243     GCTraceTime(Debug, gc, ref) tt("PhantomReference", gc_timer);
 244     process_discovered_reflist(_discoveredPhantomRefs, NULL, true,
 245                                is_alive, keep_alive, complete_gc, task_executor);
 246   }
 247 
 248   // Weak global JNI references. It would make more sense (semantically) to
 249   // traverse these simultaneously with the regular weak references above, but
 250   // that is not how the JDK1.2 specification is. See #4126360. Native code can
 251   // thus use JNI weak references to circumvent the phantom references and
 252   // resurrect a "post-mortem" object.
 253   {
 254     GCTraceTime(Debug, gc, ref) tt("JNI Weak Reference", gc_timer);
 255     if (task_executor != NULL) {
 256       task_executor->set_single_threaded_mode();
 257     }
 258     process_phaseJNI(is_alive, keep_alive, complete_gc);
 259   }
 260 
 261   size_t handled;
 262   {
 263     GCTraceTime(Debug, gc, ref) tt("Heap Monitoring Weak Reference", gc_timer);
 264     handled = process_phaseHeapSampling(is_alive, keep_alive, complete_gc, task_executor);
 265   }
 266 
 267   log_debug(gc, ref)("Ref Counts: Soft: " SIZE_FORMAT " Weak: " SIZE_FORMAT " Final: " SIZE_FORMAT " Phantom: " SIZE_FORMAT,
 268                      stats.soft_count(), stats.weak_count(), stats.final_count(), stats.phantom_count());
 269   log_develop_trace(gc, ref)("JNI Weak Reference count: " SIZE_FORMAT, count_jni_refs());
 270   log_develop_trace(gc, ref)("Heap Sampler Weak Reference handled: " SIZE_FORMAT, handled);
 271 
 272   return stats;
 273 }
 274 
 275 #ifndef PRODUCT
 276 // Calculate the number of jni handles.
 277 size_t ReferenceProcessor::count_jni_refs() {
 278   class CountHandleClosure: public OopClosure {
 279   private:
 280     size_t _count;
 281   public:
 282     CountHandleClosure(): _count(0) {}
 283     void do_oop(oop* unused)       { _count++; }
 284     void do_oop(narrowOop* unused) { ShouldNotReachHere(); }
 285     size_t count() { return _count; }
 286   };
 287   CountHandleClosure global_handle_count;
 288   JNIHandles::weak_oops_do(&global_handle_count);
 289   return global_handle_count.count();
 290 }
 291 #endif
 292 
 293 void ReferenceProcessor::process_phaseJNI(BoolObjectClosure* is_alive,
 294                                           OopClosure*        keep_alive,
 295                                           VoidClosure*       complete_gc) {
 296   JNIHandles::weak_oops_do(is_alive, keep_alive);
 297   complete_gc->do_void();
 298 }
 299 
 300 size_t ReferenceProcessor::process_phaseHeapSampling(
 301     BoolObjectClosure*           is_alive,
 302     OopClosure*                  keep_alive,
 303     VoidClosure*                 complete_gc,
 304     AbstractRefProcTaskExecutor* task_executor) {
 305   size_t count = 0;
 306   if (HeapMonitoring::enabled()) {
 307     if (task_executor != NULL) {
 308       task_executor->set_single_threaded_mode();
 309     }
 310     count = HeapMonitoring::weak_oops_do(is_alive, keep_alive);
 311     complete_gc->do_void();
 312   }
 313   return count;
 314 }
 315 
 316 void ReferenceProcessor::enqueue_discovered_references(AbstractRefProcTaskExecutor* task_executor) {
 317   // Enqueue references that are not made active again, and
 318   // clear the decks for the next collection (cycle).
 319   enqueue_discovered_reflists(task_executor);
 320 
 321   // Stop treating discovered references specially.
 322   disable_discovery();
 323 }
 324 
 325 void ReferenceProcessor::enqueue_discovered_reflist(DiscoveredList& refs_list) {
 326   // Given a list of refs linked through the "discovered" field
 327   // (java.lang.ref.Reference.discovered), self-loop their "next" field
 328   // thus distinguishing them from active References, then
 329   // prepend them to the pending list.
 330   //
 331   // The Java threads will see the Reference objects linked together through
 332   // the discovered field. Instead of trying to do the write barrier updates
 333   // in all places in the reference processor where we manipulate the discovered


< prev index next >