Mercurial > hg > truffle
comparison src/share/vm/services/memTracker.cpp @ 11198:1e6d5dec4a4e
Merge.
author | Christian Humer <christian.humer@gmail.com> |
---|---|
date | Mon, 05 Aug 2013 13:20:06 +0200 |
parents | 248c459b2b75 |
children | ce8f6bb717c9 |
comparison
equal
deleted
inserted
replaced
11197:3479ab380552 | 11198:1e6d5dec4a4e |
---|---|
67 MemTracker::ShutdownReason MemTracker::_reason = NMT_shutdown_none; | 67 MemTracker::ShutdownReason MemTracker::_reason = NMT_shutdown_none; |
68 int MemTracker::_thread_count = 255; | 68 int MemTracker::_thread_count = 255; |
69 volatile jint MemTracker::_pooled_recorder_count = 0; | 69 volatile jint MemTracker::_pooled_recorder_count = 0; |
70 volatile unsigned long MemTracker::_processing_generation = 0; | 70 volatile unsigned long MemTracker::_processing_generation = 0; |
71 volatile bool MemTracker::_worker_thread_idle = false; | 71 volatile bool MemTracker::_worker_thread_idle = false; |
72 volatile jint MemTracker::_pending_op_count = 0; | |
72 volatile bool MemTracker::_slowdown_calling_thread = false; | 73 volatile bool MemTracker::_slowdown_calling_thread = false; |
73 debug_only(intx MemTracker::_main_thread_tid = 0;) | 74 debug_only(intx MemTracker::_main_thread_tid = 0;) |
74 NOT_PRODUCT(volatile jint MemTracker::_pending_recorder_count = 0;) | 75 NOT_PRODUCT(volatile jint MemTracker::_pending_recorder_count = 0;) |
75 | 76 |
76 void MemTracker::init_tracking_options(const char* option_line) { | 77 void MemTracker::init_tracking_options(const char* option_line) { |
78 if (strcmp(option_line, "=summary") == 0) { | 79 if (strcmp(option_line, "=summary") == 0) { |
79 _tracking_level = NMT_summary; | 80 _tracking_level = NMT_summary; |
80 } else if (strcmp(option_line, "=detail") == 0) { | 81 } else if (strcmp(option_line, "=detail") == 0) { |
81 // detail relies on a stack-walking ability that may not | 82 // detail relies on a stack-walking ability that may not |
82 // be available depending on platform and/or compiler flags | 83 // be available depending on platform and/or compiler flags |
83 if (PLATFORM_NMT_DETAIL_SUPPORTED) { | 84 #if PLATFORM_NATIVE_STACK_WALKING_SUPPORTED |
84 _tracking_level = NMT_detail; | 85 _tracking_level = NMT_detail; |
85 } else { | 86 #else |
86 jio_fprintf(defaultStream::error_stream(), | 87 jio_fprintf(defaultStream::error_stream(), |
87 "NMT detail is not supported on this platform. Using NMT summary instead."); | 88 "NMT detail is not supported on this platform. Using NMT summary instead.\n"); |
88 _tracking_level = NMT_summary; | 89 _tracking_level = NMT_summary; |
89 } | 90 #endif |
90 } else if (strcmp(option_line, "=off") != 0) { | 91 } else if (strcmp(option_line, "=off") != 0) { |
91 vm_exit_during_initialization("Syntax error, expecting -XX:NativeMemoryTracking=[off|summary|detail]", NULL); | 92 vm_exit_during_initialization("Syntax error, expecting -XX:NativeMemoryTracking=[off|summary|detail]", NULL); |
92 } | 93 } |
93 } | 94 } |
94 | 95 |
335 rec->set_next(cur_head); | 336 rec->set_next(cur_head); |
336 } | 337 } |
337 Atomic::inc(&_pooled_recorder_count); | 338 Atomic::inc(&_pooled_recorder_count); |
338 } | 339 } |
339 | 340 |
340 /* | |
341 * This is the most important method in whole nmt implementation. | |
342 * | |
343 * Create a memory record. | |
344 * 1. When nmt is in single-threaded bootstrapping mode, no lock is needed as VM | |
345 * still in single thread mode. | |
346 * 2. For all threads other than JavaThread, ThreadCritical is needed | |
347 * to write to recorders to global recorder. | |
348 * 3. For JavaThreads that are not longer visible by safepoint, also | |
349 * need to take ThreadCritical and records are written to global | |
350 * recorders, since these threads are NOT walked by Threads.do_thread(). | |
351 * 4. JavaThreads that are running in native state, have to transition | |
352 * to VM state before writing to per-thread recorders. | |
353 * 5. JavaThreads that are running in VM state do not need any lock and | |
354 * records are written to per-thread recorders. | |
355 * 6. For a thread has yet to attach VM 'Thread', they need to take | |
356 * ThreadCritical to write to global recorder. | |
357 * | |
358 * Important note: | |
359 * NO LOCK should be taken inside ThreadCritical lock !!! | |
360 */ | |
361 void MemTracker::create_memory_record(address addr, MEMFLAGS flags, | |
362 size_t size, address pc, Thread* thread) { | |
363 assert(addr != NULL, "Sanity check"); | |
364 if (!shutdown_in_progress()) { | |
365 // single thread, we just write records direct to global recorder,' | |
366 // with any lock | |
367 if (_state == NMT_bootstrapping_single_thread) { | |
368 assert(_main_thread_tid == os::current_thread_id(), "wrong thread"); | |
369 thread = NULL; | |
370 } else { | |
371 if (thread == NULL) { | |
372 // don't use Thread::current(), since it is possible that | |
373 // the calling thread has yet to attach to VM 'Thread', | |
374 // which will result assertion failure | |
375 thread = ThreadLocalStorage::thread(); | |
376 } | |
377 } | |
378 | |
379 if (thread != NULL) { | |
380 // slow down all calling threads except NMT worker thread, so it | |
381 // can catch up. | |
382 if (_slowdown_calling_thread && thread != _worker_thread) { | |
383 os::yield_all(); | |
384 } | |
385 | |
386 if (thread->is_Java_thread() && ((JavaThread*)thread)->is_safepoint_visible()) { | |
387 JavaThread* java_thread = (JavaThread*)thread; | |
388 JavaThreadState state = java_thread->thread_state(); | |
389 if (SafepointSynchronize::safepoint_safe(java_thread, state)) { | |
390 // JavaThreads that are safepoint safe, can run through safepoint, | |
391 // so ThreadCritical is needed to ensure no threads at safepoint create | |
392 // new records while the records are being gathered and the sequence number is changing | |
393 ThreadCritical tc; | |
394 create_record_in_recorder(addr, flags, size, pc, java_thread); | |
395 } else { | |
396 create_record_in_recorder(addr, flags, size, pc, java_thread); | |
397 } | |
398 } else { | |
399 // other threads, such as worker and watcher threads, etc. need to | |
400 // take ThreadCritical to write to global recorder | |
401 ThreadCritical tc; | |
402 create_record_in_recorder(addr, flags, size, pc, NULL); | |
403 } | |
404 } else { | |
405 if (_state == NMT_bootstrapping_single_thread) { | |
406 // single thread, no lock needed | |
407 create_record_in_recorder(addr, flags, size, pc, NULL); | |
408 } else { | |
409 // for thread has yet to attach VM 'Thread', we can not use VM mutex. | |
410 // use native thread critical instead | |
411 ThreadCritical tc; | |
412 create_record_in_recorder(addr, flags, size, pc, NULL); | |
413 } | |
414 } | |
415 } | |
416 } | |
417 | |
418 // write a record to proper recorder. No lock can be taken from this method | 341 // write a record to proper recorder. No lock can be taken from this method |
419 // down. | 342 // down. |
420 void MemTracker::create_record_in_recorder(address addr, MEMFLAGS flags, | 343 void MemTracker::write_tracking_record(address addr, MEMFLAGS flags, |
421 size_t size, address pc, JavaThread* thread) { | 344 size_t size, jint seq, address pc, JavaThread* thread) { |
422 | 345 |
423 MemRecorder* rc = get_thread_recorder(thread); | 346 MemRecorder* rc = get_thread_recorder(thread); |
424 if (rc != NULL) { | 347 if (rc != NULL) { |
425 rc->record(addr, flags, size, pc); | 348 rc->record(addr, flags, size, seq, pc); |
426 } | 349 } |
427 } | 350 } |
428 | 351 |
429 /** | 352 /** |
430 * enqueue a recorder to pending queue | 353 * enqueue a recorder to pending queue |
460 */ | 383 */ |
461 #define MAX_SAFEPOINTS_TO_SKIP 128 | 384 #define MAX_SAFEPOINTS_TO_SKIP 128 |
462 #define SAFE_SEQUENCE_THRESHOLD 30 | 385 #define SAFE_SEQUENCE_THRESHOLD 30 |
463 #define HIGH_GENERATION_THRESHOLD 60 | 386 #define HIGH_GENERATION_THRESHOLD 60 |
464 #define MAX_RECORDER_THREAD_RATIO 30 | 387 #define MAX_RECORDER_THREAD_RATIO 30 |
388 #define MAX_RECORDER_PER_THREAD 100 | |
465 | 389 |
466 void MemTracker::sync() { | 390 void MemTracker::sync() { |
467 assert(_tracking_level > NMT_off, "NMT is not enabled"); | 391 assert(_tracking_level > NMT_off, "NMT is not enabled"); |
468 assert(SafepointSynchronize::is_at_safepoint(), "Safepoint required"); | 392 assert(SafepointSynchronize::is_at_safepoint(), "Safepoint required"); |
469 | 393 |
485 if (per_seq_in_use < SAFE_SEQUENCE_THRESHOLD && per_gen_in_use >= HIGH_GENERATION_THRESHOLD) { | 409 if (per_seq_in_use < SAFE_SEQUENCE_THRESHOLD && per_gen_in_use >= HIGH_GENERATION_THRESHOLD) { |
486 _sync_point_skip_count ++; | 410 _sync_point_skip_count ++; |
487 return; | 411 return; |
488 } | 412 } |
489 } | 413 } |
490 _sync_point_skip_count = 0; | |
491 { | 414 { |
492 // This method is running at safepoint, with ThreadCritical lock, | 415 // This method is running at safepoint, with ThreadCritical lock, |
493 // it should guarantee that NMT is fully sync-ed. | 416 // it should guarantee that NMT is fully sync-ed. |
494 ThreadCritical tc; | 417 ThreadCritical tc; |
495 | 418 |
496 SequenceGenerator::reset(); | 419 // We can NOT execute NMT sync-point if there are pending tracking ops. |
497 | 420 if (_pending_op_count == 0) { |
498 // walk all JavaThreads to collect recorders | 421 SequenceGenerator::reset(); |
499 SyncThreadRecorderClosure stc; | 422 _sync_point_skip_count = 0; |
500 Threads::threads_do(&stc); | 423 |
501 | 424 // walk all JavaThreads to collect recorders |
502 _thread_count = stc.get_thread_count(); | 425 SyncThreadRecorderClosure stc; |
503 MemRecorder* pending_recorders = get_pending_recorders(); | 426 Threads::threads_do(&stc); |
504 | 427 |
505 if (_global_recorder != NULL) { | 428 _thread_count = stc.get_thread_count(); |
506 _global_recorder->set_next(pending_recorders); | 429 MemRecorder* pending_recorders = get_pending_recorders(); |
507 pending_recorders = _global_recorder; | 430 |
508 _global_recorder = NULL; | 431 if (_global_recorder != NULL) { |
432 _global_recorder->set_next(pending_recorders); | |
433 pending_recorders = _global_recorder; | |
434 _global_recorder = NULL; | |
435 } | |
436 | |
437 // see if NMT has too many outstanding recorder instances, it usually | |
438 // means that worker thread is lagging behind in processing them. | |
439 if (!AutoShutdownNMT) { | |
440 _slowdown_calling_thread = (MemRecorder::_instance_count > MAX_RECORDER_THREAD_RATIO * _thread_count); | |
441 } else { | |
442 // If auto shutdown is on, enforce MAX_RECORDER_PER_THREAD threshold to prevent OOM | |
443 if (MemRecorder::_instance_count >= _thread_count * MAX_RECORDER_PER_THREAD) { | |
444 shutdown(NMT_out_of_memory); | |
445 } | |
446 } | |
447 | |
448 // check _worker_thread with lock to avoid racing condition | |
449 if (_worker_thread != NULL) { | |
450 _worker_thread->at_sync_point(pending_recorders, InstanceKlass::number_of_instance_classes()); | |
451 } | |
452 assert(SequenceGenerator::peek() == 1, "Should not have memory activities during sync-point"); | |
453 } else { | |
454 _sync_point_skip_count ++; | |
509 } | 455 } |
510 | |
511 // see if NMT has too many outstanding recorder instances, it usually | |
512 // means that worker thread is lagging behind in processing them. | |
513 if (!AutoShutdownNMT) { | |
514 _slowdown_calling_thread = (MemRecorder::_instance_count > MAX_RECORDER_THREAD_RATIO * _thread_count); | |
515 } | |
516 | |
517 // check _worker_thread with lock to avoid racing condition | |
518 if (_worker_thread != NULL) { | |
519 _worker_thread->at_sync_point(pending_recorders, InstanceKlass::number_of_instance_classes()); | |
520 } | |
521 | |
522 assert(SequenceGenerator::peek() == 1, "Should not have memory activities during sync-point"); | |
523 } | 456 } |
524 } | 457 } |
525 | 458 |
526 // now, it is the time to shut whole things off | 459 // now, it is the time to shut whole things off |
527 if (_state == NMT_final_shutdown) { | 460 if (_state == NMT_final_shutdown) { |
706 st->print_cr("No snapshot"); | 639 st->print_cr("No snapshot"); |
707 } | 640 } |
708 } | 641 } |
709 #endif | 642 #endif |
710 | 643 |
644 | |
645 // Tracker Implementation | |
646 | |
647 /* | |
648 * Create a tracker. | |
649 * This is a fairly complicated constructor, as it has to make two important decisions: | |
650 * 1) Does it need to take ThreadCritical lock to write tracking record | |
651 * 2) Does it need to pre-reserve a sequence number for the tracking record | |
652 * | |
653 * The rules to determine if ThreadCritical is needed: | |
654 * 1. When nmt is in single-threaded bootstrapping mode, no lock is needed as VM | |
655 * still in single thread mode. | |
656 * 2. For all threads other than JavaThread, ThreadCritical is needed | |
657 * to write to recorders to global recorder. | |
658 * 3. For JavaThreads that are no longer visible by safepoint, also | |
659 * need to take ThreadCritical and records are written to global | |
660 * recorders, since these threads are NOT walked by Threads.do_thread(). | |
661 * 4. JavaThreads that are running in safepoint-safe states do not stop | |
662 * for safepoints, ThreadCritical lock should be taken to write | |
663 * memory records. | |
664 * 5. JavaThreads that are running in VM state do not need any lock and | |
665 * records are written to per-thread recorders. | |
666 * 6. For a thread has yet to attach VM 'Thread', they need to take | |
667 * ThreadCritical to write to global recorder. | |
668 * | |
669 * The memory operations that need pre-reserve sequence numbers: | |
670 * The memory operations that "release" memory blocks and the | |
671 * operations can fail, need to pre-reserve sequence number. They | |
672 * are realloc, uncommit and release. | |
673 * | |
674 * The reason for pre-reserve sequence number, is to prevent race condition: | |
675 * Thread 1 Thread 2 | |
676 * <release> | |
677 * <allocate> | |
678 * <write allocate record> | |
679 * <write release record> | |
680 * if Thread 2 happens to obtain the memory address Thread 1 just released, | |
681 * then NMT can mistakenly report the memory is free. | |
682 * | |
683 * Noticeably, free() does not need pre-reserve sequence number, because the call | |
684 * does not fail, so we can alway write "release" record before the memory is actaully | |
685 * freed. | |
686 * | |
687 * For realloc, uncommit and release, following coding pattern should be used: | |
688 * | |
689 * MemTracker::Tracker tkr = MemTracker::get_realloc_tracker(); | |
690 * ptr = ::realloc(...); | |
691 * if (ptr == NULL) { | |
692 * tkr.record(...) | |
693 * } else { | |
694 * tkr.discard(); | |
695 * } | |
696 * | |
697 * MemTracker::Tracker tkr = MemTracker::get_virtual_memory_uncommit_tracker(); | |
698 * if (uncommit(...)) { | |
699 * tkr.record(...); | |
700 * } else { | |
701 * tkr.discard(); | |
702 * } | |
703 * | |
704 * MemTracker::Tracker tkr = MemTracker::get_virtual_memory_release_tracker(); | |
705 * if (release(...)) { | |
706 * tkr.record(...); | |
707 * } else { | |
708 * tkr.discard(); | |
709 * } | |
710 * | |
711 * Since pre-reserved sequence number is only good for the generation that it is acquired, | |
712 * when there is pending Tracker that reserved sequence number, NMT sync-point has | |
713 * to be skipped to prevent from advancing generation. This is done by inc and dec | |
714 * MemTracker::_pending_op_count, when MemTracker::_pending_op_count > 0, NMT sync-point is skipped. | |
715 * Not all pre-reservation of sequence number will increment pending op count. For JavaThreads | |
716 * that honor safepoints, safepoint can not occur during the memory operations, so the | |
717 * pre-reserved sequence number won't cross the generation boundry. | |
718 */ | |
719 MemTracker::Tracker::Tracker(MemoryOperation op, Thread* thr) { | |
720 _op = NoOp; | |
721 _seq = 0; | |
722 if (MemTracker::is_on()) { | |
723 _java_thread = NULL; | |
724 _op = op; | |
725 | |
726 // figure out if ThreadCritical lock is needed to write this operation | |
727 // to MemTracker | |
728 if (MemTracker::is_single_threaded_bootstrap()) { | |
729 thr = NULL; | |
730 } else if (thr == NULL) { | |
731 // don't use Thread::current(), since it is possible that | |
732 // the calling thread has yet to attach to VM 'Thread', | |
733 // which will result assertion failure | |
734 thr = ThreadLocalStorage::thread(); | |
735 } | |
736 | |
737 if (thr != NULL) { | |
738 // Check NMT load | |
739 MemTracker::check_NMT_load(thr); | |
740 | |
741 if (thr->is_Java_thread() && ((JavaThread*)thr)->is_safepoint_visible()) { | |
742 _java_thread = (JavaThread*)thr; | |
743 JavaThreadState state = _java_thread->thread_state(); | |
744 // JavaThreads that are safepoint safe, can run through safepoint, | |
745 // so ThreadCritical is needed to ensure no threads at safepoint create | |
746 // new records while the records are being gathered and the sequence number is changing | |
747 _need_thread_critical_lock = | |
748 SafepointSynchronize::safepoint_safe(_java_thread, state); | |
749 } else { | |
750 _need_thread_critical_lock = true; | |
751 } | |
752 } else { | |
753 _need_thread_critical_lock | |
754 = !MemTracker::is_single_threaded_bootstrap(); | |
755 } | |
756 | |
757 // see if we need to pre-reserve sequence number for this operation | |
758 if (_op == Realloc || _op == Uncommit || _op == Release) { | |
759 if (_need_thread_critical_lock) { | |
760 ThreadCritical tc; | |
761 MemTracker::inc_pending_op_count(); | |
762 _seq = SequenceGenerator::next(); | |
763 } else { | |
764 // for the threads that honor safepoints, no safepoint can occur | |
765 // during the lifespan of tracker, so we don't need to increase | |
766 // pending op count. | |
767 _seq = SequenceGenerator::next(); | |
768 } | |
769 } | |
770 } | |
771 } | |
772 | |
773 void MemTracker::Tracker::discard() { | |
774 if (MemTracker::is_on() && _seq != 0) { | |
775 if (_need_thread_critical_lock) { | |
776 ThreadCritical tc; | |
777 MemTracker::dec_pending_op_count(); | |
778 } | |
779 _seq = 0; | |
780 } | |
781 } | |
782 | |
783 | |
784 void MemTracker::Tracker::record(address old_addr, address new_addr, size_t size, | |
785 MEMFLAGS flags, address pc) { | |
786 assert(old_addr != NULL && new_addr != NULL, "Sanity check"); | |
787 assert(_op == Realloc || _op == NoOp, "Wrong call"); | |
788 if (MemTracker::is_on() && NMT_CAN_TRACK(flags) && _op != NoOp) { | |
789 assert(_seq > 0, "Need pre-reserve sequence number"); | |
790 if (_need_thread_critical_lock) { | |
791 ThreadCritical tc; | |
792 // free old address, use pre-reserved sequence number | |
793 MemTracker::write_tracking_record(old_addr, MemPointerRecord::free_tag(), | |
794 0, _seq, pc, _java_thread); | |
795 MemTracker::write_tracking_record(new_addr, flags | MemPointerRecord::malloc_tag(), | |
796 size, SequenceGenerator::next(), pc, _java_thread); | |
797 // decrement MemTracker pending_op_count | |
798 MemTracker::dec_pending_op_count(); | |
799 } else { | |
800 // free old address, use pre-reserved sequence number | |
801 MemTracker::write_tracking_record(old_addr, MemPointerRecord::free_tag(), | |
802 0, _seq, pc, _java_thread); | |
803 MemTracker::write_tracking_record(new_addr, flags | MemPointerRecord::malloc_tag(), | |
804 size, SequenceGenerator::next(), pc, _java_thread); | |
805 } | |
806 _seq = 0; | |
807 } | |
808 } | |
809 | |
810 void MemTracker::Tracker::record(address addr, size_t size, MEMFLAGS flags, address pc) { | |
811 // OOM already? | |
812 if (addr == NULL) return; | |
813 | |
814 if (MemTracker::is_on() && NMT_CAN_TRACK(flags) && _op != NoOp) { | |
815 bool pre_reserved_seq = (_seq != 0); | |
816 address pc = CALLER_CALLER_PC; | |
817 MEMFLAGS orig_flags = flags; | |
818 | |
819 // or the tagging flags | |
820 switch(_op) { | |
821 case Malloc: | |
822 flags |= MemPointerRecord::malloc_tag(); | |
823 break; | |
824 case Free: | |
825 flags = MemPointerRecord::free_tag(); | |
826 break; | |
827 case Realloc: | |
828 fatal("Use the other Tracker::record()"); | |
829 break; | |
830 case Reserve: | |
831 case ReserveAndCommit: | |
832 flags |= MemPointerRecord::virtual_memory_reserve_tag(); | |
833 break; | |
834 case Commit: | |
835 flags = MemPointerRecord::virtual_memory_commit_tag(); | |
836 break; | |
837 case Type: | |
838 flags |= MemPointerRecord::virtual_memory_type_tag(); | |
839 break; | |
840 case Uncommit: | |
841 assert(pre_reserved_seq, "Need pre-reserve sequence number"); | |
842 flags = MemPointerRecord::virtual_memory_uncommit_tag(); | |
843 break; | |
844 case Release: | |
845 assert(pre_reserved_seq, "Need pre-reserve sequence number"); | |
846 flags = MemPointerRecord::virtual_memory_release_tag(); | |
847 break; | |
848 case ArenaSize: | |
849 // a bit of hack here, add a small postive offset to arena | |
850 // address for its size record, so the size record is sorted | |
851 // right after arena record. | |
852 flags = MemPointerRecord::arena_size_tag(); | |
853 addr += sizeof(void*); | |
854 break; | |
855 case StackRelease: | |
856 flags = MemPointerRecord::virtual_memory_release_tag(); | |
857 break; | |
858 default: | |
859 ShouldNotReachHere(); | |
860 } | |
861 | |
862 // write memory tracking record | |
863 if (_need_thread_critical_lock) { | |
864 ThreadCritical tc; | |
865 if (_seq == 0) _seq = SequenceGenerator::next(); | |
866 MemTracker::write_tracking_record(addr, flags, size, _seq, pc, _java_thread); | |
867 if (_op == ReserveAndCommit) { | |
868 MemTracker::write_tracking_record(addr, orig_flags | MemPointerRecord::virtual_memory_commit_tag(), | |
869 size, SequenceGenerator::next(), pc, _java_thread); | |
870 } | |
871 if (pre_reserved_seq) MemTracker::dec_pending_op_count(); | |
872 } else { | |
873 if (_seq == 0) _seq = SequenceGenerator::next(); | |
874 MemTracker::write_tracking_record(addr, flags, size, _seq, pc, _java_thread); | |
875 if (_op == ReserveAndCommit) { | |
876 MemTracker::write_tracking_record(addr, orig_flags | MemPointerRecord::virtual_memory_commit_tag(), | |
877 size, SequenceGenerator::next(), pc, _java_thread); | |
878 } | |
879 } | |
880 _seq = 0; | |
881 } | |
882 } | |
883 |