--- old/src/share/vm/services/memRecorder.cpp Fri Jul 13 08:04:35 2012 +++ new/src/share/vm/services/memRecorder.cpp Fri Jul 13 08:04:33 2012 @@ -45,11 +45,11 @@ } -debug_only(volatile jint MemRecorder::_instance_count = 0;) +volatile jint MemRecorder::_instance_count = 0; MemRecorder::MemRecorder() { assert(MemTracker::is_on(), "Native memory tracking is off"); - debug_only(Atomic::inc(&_instance_count);) + Atomic::inc(&_instance_count); debug_only(set_generation();) if (MemTracker::track_callsite()) { @@ -83,9 +83,7 @@ delete _next; } -#ifdef ASSERT Atomic::dec(&_instance_count); -#endif } // Sorting order: --- old/src/share/vm/services/memRecorder.hpp Fri Jul 13 08:04:41 2012 +++ new/src/share/vm/services/memRecorder.hpp Fri Jul 13 08:04:40 2012 @@ -249,9 +249,9 @@ SequencedRecordIterator pointer_itr(); - public: + protected: // number of MemRecorder instance - debug_only(static volatile jint _instance_count;) + static volatile jint _instance_count; private: // sorting function, sort records into following order --- old/src/share/vm/services/memTrackWorker.hpp Fri Jul 13 08:04:47 2012 +++ new/src/share/vm/services/memTrackWorker.hpp Fri Jul 13 08:04:46 2012 @@ -67,7 +67,7 @@ NOT_PRODUCT(int _last_gen_in_use;) inline int generations_in_use() const { - return (_tail <= _head ? (_head - _tail + 1) : (MAX_GENERATIONS - (_tail - _head) + 1)); + return (_tail >= _head ? (_tail - _head + 1) : (MAX_GENERATIONS - (_head - _tail) + 1)); } }; --- old/src/share/vm/services/memTracker.cpp Fri Jul 13 08:04:54 2012 +++ new/src/share/vm/services/memTracker.cpp Fri Jul 13 08:04:52 2012 @@ -361,6 +361,10 @@ // VM state, so it can stop at safepoint. JavaThread running in VM state does not // need lock to write records. if (thread->is_Java_thread() && ((JavaThread*)thread)->is_safepoint_visible()) { + assert(!(SafepointSynchronize::is_at_safepoint() && + ((JavaThread*)thread)->thread_state() == _thread_blocked), + "_thread_blocked allocate/deallocation memory at safepoint"); + if (((JavaThread*)thread)->thread_state() == _thread_in_native) { ThreadInVMfromNative trans((JavaThread*)thread); create_record_in_recorder(addr, flags, size, pc, thread); @@ -486,8 +490,6 @@ // now, it is the time to shut whole things off if (_state == NMT_final_shutdown) { - _tracking_level = NMT_off; - // walk all JavaThreads to delete all recorders SyncThreadRecorderClosure stc; Threads::threads_do(&stc); @@ -499,8 +501,16 @@ _global_recorder = NULL; } } - - _state = NMT_shutdown; + MemRecorder* pending_recorders = get_pending_recorders(); + if (pending_recorders != NULL) { + delete pending_recorders; + } + // wait until MemRecorder instance drops to zero to + // completely shutdown NMT + if (MemRecorder::_instance_count == 0) { + _state = NMT_shutdown; + _tracking_level = NMT_off; + } } }