comparison src/share/vm/services/memTracker.cpp @ 6231:7e5976e66c62

7182543: NMT ON: Aggregate a few NMT related bugs Summary: 1) Fixed MemTrackWorker::generations_in_used() calculation 2) Ensured NMT not to leak memory recorders after shutdown 3) Used ThreadCritical to block safepoint safe threads Reviewed-by: acorn, coleenp, dholmes, kvn
author zgu
date Thu, 19 Jul 2012 09:05:42 -0400
parents d2a62e0f25eb
children d5bc62fcfac7
comparison
equal deleted inserted replaced
6201:ace99a6ffc83 6231:7e5976e66c62
349 thread = ThreadLocalStorage::thread(); 349 thread = ThreadLocalStorage::thread();
350 } 350 }
351 } 351 }
352 352
353 if (thread != NULL) { 353 if (thread != NULL) {
354 #ifdef ASSERT
355 // cause assertion on stack base. This ensures that threads call
356 // Thread::record_stack_base_and_size() method, which will create
357 // thread native stack records.
358 thread->stack_base();
359 #endif
360 // for a JavaThread, if it is running in native state, we need to transition it to
361 // VM state, so it can stop at safepoint. JavaThread running in VM state does not
362 // need lock to write records.
363 if (thread->is_Java_thread() && ((JavaThread*)thread)->is_safepoint_visible()) { 354 if (thread->is_Java_thread() && ((JavaThread*)thread)->is_safepoint_visible()) {
364 if (((JavaThread*)thread)->thread_state() == _thread_in_native) { 355 JavaThread* java_thread = static_cast<JavaThread*>(thread);
365 ThreadInVMfromNative trans((JavaThread*)thread); 356 JavaThreadState state = java_thread->thread_state();
366 create_record_in_recorder(addr, flags, size, pc, thread); 357 if (SafepointSynchronize::safepoint_safe(java_thread, state)) {
358 // JavaThreads that are safepoint safe, can run through safepoint,
359 // so ThreadCritical is needed to ensure no threads at safepoint create
360 // new records while the records are being gathered and the sequence number is changing
361 ThreadCritical tc;
362 create_record_in_recorder(addr, flags, size, pc, java_thread);
367 } else { 363 } else {
368 create_record_in_recorder(addr, flags, size, pc, thread); 364 create_record_in_recorder(addr, flags, size, pc, java_thread);
369 } 365 }
370 } else { 366 } else {
371 // other threads, such as worker and watcher threads, etc. need to 367 // other threads, such as worker and watcher threads, etc. need to
372 // take ThreadCritical to write to global recorder 368 // take ThreadCritical to write to global recorder
373 ThreadCritical tc; 369 ThreadCritical tc;
388 } 384 }
389 385
390 // write a record to proper recorder. No lock can be taken from this method 386 // write a record to proper recorder. No lock can be taken from this method
391 // down. 387 // down.
392 void MemTracker::create_record_in_recorder(address addr, MEMFLAGS flags, 388 void MemTracker::create_record_in_recorder(address addr, MEMFLAGS flags,
393 size_t size, address pc, Thread* thread) { 389 size_t size, address pc, JavaThread* thread) {
394 assert(thread == NULL || thread->is_Java_thread(), "wrong thread"); 390
395 391 MemRecorder* rc = get_thread_recorder(thread);
396 MemRecorder* rc = get_thread_recorder((JavaThread*)thread);
397 if (rc != NULL) { 392 if (rc != NULL) {
398 rc->record(addr, flags, size, pc); 393 rc->record(addr, flags, size, pc);
399 } 394 }
400 } 395 }
401 396
458 _sync_point_skip_count ++; 453 _sync_point_skip_count ++;
459 return; 454 return;
460 } 455 }
461 } 456 }
462 _sync_point_skip_count = 0; 457 _sync_point_skip_count = 0;
463 // walk all JavaThreads to collect recorders
464 SyncThreadRecorderClosure stc;
465 Threads::threads_do(&stc);
466
467 _thread_count = stc.get_thread_count();
468 MemRecorder* pending_recorders = get_pending_recorders();
469
470 { 458 {
471 // This method is running at safepoint, with ThreadCritical lock, 459 // This method is running at safepoint, with ThreadCritical lock,
472 // it should guarantee that NMT is fully sync-ed. 460 // it should guarantee that NMT is fully sync-ed.
473 ThreadCritical tc; 461 ThreadCritical tc;
462
463 // walk all JavaThreads to collect recorders
464 SyncThreadRecorderClosure stc;
465 Threads::threads_do(&stc);
466
467 _thread_count = stc.get_thread_count();
468 MemRecorder* pending_recorders = get_pending_recorders();
469
474 if (_global_recorder != NULL) { 470 if (_global_recorder != NULL) {
475 _global_recorder->set_next(pending_recorders); 471 _global_recorder->set_next(pending_recorders);
476 pending_recorders = _global_recorder; 472 pending_recorders = _global_recorder;
477 _global_recorder = NULL; 473 _global_recorder = NULL;
478 } 474 }
484 } 480 }
485 } 481 }
486 482
487 // now, it is the time to shut whole things off 483 // now, it is the time to shut whole things off
488 if (_state == NMT_final_shutdown) { 484 if (_state == NMT_final_shutdown) {
489 _tracking_level = NMT_off;
490
491 // walk all JavaThreads to delete all recorders 485 // walk all JavaThreads to delete all recorders
492 SyncThreadRecorderClosure stc; 486 SyncThreadRecorderClosure stc;
493 Threads::threads_do(&stc); 487 Threads::threads_do(&stc);
494 // delete global recorder 488 // delete global recorder
495 { 489 {
497 if (_global_recorder != NULL) { 491 if (_global_recorder != NULL) {
498 delete _global_recorder; 492 delete _global_recorder;
499 _global_recorder = NULL; 493 _global_recorder = NULL;
500 } 494 }
501 } 495 }
502 496 MemRecorder* pending_recorders = get_pending_recorders();
503 _state = NMT_shutdown; 497 if (pending_recorders != NULL) {
498 delete pending_recorders;
499 }
500 // try at a later sync point to ensure MemRecorder instance drops to zero to
501 // completely shutdown NMT
502 if (MemRecorder::_instance_count == 0) {
503 _state = NMT_shutdown;
504 _tracking_level = NMT_off;
505 }
504 } 506 }
505 } 507 }
506 508
507 /* 509 /*
508 * Start worker thread. 510 * Start worker thread.