Other | Other |
---|---|
5.0u18-rev b03Fixed | 5.0u19Fixed |
Duplicate :
|
|
Duplicate :
|
|
Duplicate :
|
|
Relates :
|
When a customer used JVMTI in jdk5, memory leaks. Specifically speaking, when a callback function is set for the event of JVMTI_EVENT_THREAD_START, this leak occurs. The following source code portions are based on jdk5.0u16. When a call back function is set for the event of JVMTI_EVENT_THREAD_START, every time Java application creates threads, JvmtiThreadState is created in JVM. At the line# 49( constructor of JvmtiThreadState and GrowableArray), the second argument is set to true. ---- [hotspot/src/share/vm/prims/jvmtiThreadState.cpp] 30 JvmtiThreadState::JvmtiThreadState(JavaThread* thread) ... 47 // add all the JvmtiEnvThreadState to the new JvmtiThreadState 48 int ec = JvmtiEnvBase::env_count(); 49 _env_thread_states = new (ResourceObj::C_HEAP) GrowableArray<JvmtiEnvThreadState *>(ec+1,true); ... 66 } ----- When the second argument is true, the field "_data" in GrowableArray is allocated to c heap. Because there is no destructor for GrowableArray, to call clear_and_deallocate() and release _data are needed before the release of GrowableArray. [hotspot/src/share/vm/utilities/growableArray.cpp] 31 GenericGrowableArray::GenericGrowableArray(int initial_size, int initial_len, GrET* filler, bool c_heap) { 32 _len = initial_len; 33 _max = initial_size; 34 assert(_len >= 0 && _len <= _max, "initial_len too big"); 35 _arena = (c_heap ? (Arena*)1 : NULL); 36 if (on_C_heap()) { 37 _data = NEW_C_HEAP_ARRAY(GrET*, _max); 38 } else { 39 _data = NEW_RESOURCE_ARRAY(GrET*, _max); 40 } 41 for (int i = 0; i < _len; i++) _data[i] = filler; 42 #ifdef ASSERT 43 if (!on_C_heap()) { 44 _nesting = Thread::current()->resource_area()->nesting(); 45 } 46 #endif 47 } ... 222 void GenericGrowableArray::clear_and_deallocate() { 223 assert(on_C_heap(), 224 "clear_and_deallocate should only be called when on C heap"); 225 clear(); 226 if (_data != NULL) { 227 FreeHeap(_data); 228 _data = NULL; 229 } 230 } However, there is no call for clear_and_deallocate() before _env_thread_states is discarded in destructor, ~JvmtiThreadState(). [hotspot/src/share/vm/prims/jvmtiThreadState.cpp] 69 JvmtiThreadState::~JvmtiThreadState() { ... 79 int ec = env_count(); 80 assert(ec == JvmtiEnvBase::env_count(), "Should be one JvmtiEnvThreadState per environment"); 81 for (int i = 0; i < ec ; ++i) { 82 JvmtiEnvThreadState *ets = _env_thread_states->at(i); 83 _env_thread_states->at_put(i, NULL); 84 delete ets; 85 } 86 FreeHeap(_env_thread_states); 87 _env_thread_states = NULL; So, every time JvmtiThreadState is created, which is, application creates threads, memory will leak.
|