JDK-6751861 : Memory leak occurs in JVMTI(jdk5.0u16)
  • Type: Bug
  • Component: hotspot
  • Sub-Component: jvmti
  • Affected Version: 5.0,5.0u16
  • Priority: P3
  • Status: Resolved
  • Resolution: Fixed
  • OS: linux_redhat_3.0,windows_xp
  • CPU: x86
  • Submitted: 2008-09-24
  • Updated: 2011-02-16
  • Resolved: 2009-03-09
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
Other Other
5.0u18-rev b03Fixed 5.0u19Fixed
Related Reports
Duplicate :  
Duplicate :  
Duplicate :  
Relates :  
Description
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.

Comments
SUGGESTED FIX http://jpsesvr.sfbay.sun.com:8080/ctetools/CodeStore/2815/webrev/index.html
21-01-2009

EVALUATION The bug description does not mention if the customer has tried jdk6 but the issue should already been fixed via the changes for the more general problem that was 6306746. Furthermore, this code was subsequently replaced in jdk6 but the changes for 6369191 and 6452240.
24-09-2008