United StatesChange Country, Oracle Worldwide Web Sites Communities I am a... I want to...
Bug ID: JDK-6306741 Memory leaks of C-heap allocated ResourceObjs
JDK-6306741 : Memory leaks of C-heap allocated ResourceObjs

Details
Type:
Bug
Submit Date:
2005-08-05
Status:
Resolved
Updated Date:
2010-04-02
Project Name:
JDK
Resolved Date:
2005-09-17
Component:
hotspot
OS:
generic
Sub-Component:
gc
CPU:
generic
Priority:
P2
Resolution:
Fixed
Affected Versions:
2.0,6
Fixed Versions:

Related Reports
Backport:
Backport:
Duplicate:
Relates:
Relates:
Relates:

Sub Tasks

Description
-
-
-
Certain GrowableArrays are being allocated with the "C_heap" flag set
to true but without the ResourceObj::C_HEAP flag being passed to
operator new for the GrowableArray object itself. This is a problem
because it is very easy to accidentally allocate the GrowableArray
underneath a ResourceMark which is later cleared, which will cause the
storage for the GrowableArray object itself (including nesting, arena,
and data pointer flags) to be overwritten later. This can cause
crashes in product mode and/or assertion failures in debug mode. In
the absence of assertions that the allocation class of the
GrowableArray matches that of its contained data array, these
allocation sites should be fixed to pass ResourceObj::C_HEAP as
argument to operator new. It is possible that these sites are benign
because the allocation is being done at a point where the ResourceMark
nesting is known, but if we add assertion checking later then these
allocation sites will fail.

When making this change the responsible engineer should be careful not
to introduce new memory leaks. In particular, the following cleanup
sequence for these arrays should be obeyed:

  array->clear_and_deallocate();
  delete array; // call destructors, but ResourceObj destructor
                // doesn't free memory which was allocated in 
                // the C-heap with malloc
  FreeHeap(Array);  // ... so use this to free the memory

See Label::free() in assembler.hpp for an example.

The relevant allocation sites for this group's code are attached.
Adding specifics to the description for gc:

hotspot/garbage_collector:
src/share/vm/gc_implementation/parallelScavenge/psScavenge.cpp:540:      _preserved_oop_stack = new (ResourceObj::C_HEAP) GrowableArray<oop>(40, true);
src/share/vm/gc_implementation/parallelScavenge/psScavenge.cpp:539:      _preserved_mark_stack = new (ResourceObj::C_HEAP) GrowableArray<markOop>(40, true);
src/share/vm/gc_implementation/shared/markSweep.cpp:118:      _preserved_mark_stack = new (ResourceObj::C_HEAP) GrowableArray<markOop>(40, true);
src/share/vm/gc_implementation/shared/markSweep.cpp:119:      _preserved_oop_stack = new (ResourceObj::C_HEAP) GrowableArray<oop>(40, true);
   - stacks are deleted but FreeHeap is not called on them
src/share/vm/memory/defNewGeneration.cpp:595:      _objs_with_preserved_marks = new (ResourceObj::C_HEAP)
src/share/vm/memory/defNewGeneration.cpp:597:      _preserved_marks_of_objs = new (ResourceObj::C_HEAP)
   - stacks are deleted but FreeHeap is not called on them; also, no
     clear_and_deallocate is called (** SERIOUS **)
   - genMarkSweep.cpp: _preserved_mark_stack and _preserved_oop_stack:
     call FreeHeap after operator delete

                                    

Comments
EVALUATION

###@###.### has the fixes; under testing and review.
                                     
2005-08-26
EVALUATION

Fixed 6306746: Add assertions to GrowableArray and ResourceObj
Fixed 6306730: Incorrect management of C-heap GrowableArrays (gc)
Fixed 6306736: Incorrect management of C-heap (jvmti)
Fixed 6306741: Memory leaks of C-heap allocated ResourceObjs (gc)
Fixed 6306743: Memory leaks of C-heap allocated ResourceObjs (jvmti)
Fixed 6306745: Memory leaks of C-heap allocated ResourceObjs (runtime)
Fixed 6306738: Memory leaks of C-heap allocated ResourceObjs (c2)

Require GrowableArrays whose elements are allocated on the C heap to also
be allocated on the C heap.  This prevents leaking the GrowableArray object
itself or worse, having it go out of scope of it's containing ResourceMark.
Which is usually why C_heap was used for the arguments themselves.

I added a field to ResourceObj to track whether new allocates on c_heap,
resource area, or arena, and implemented the ResourceObj::operator delete
to call FreeHeap() if the allocation was on C heap.  An assert was added
to the delete() operator to check that delete can only be called on a
C_HEAP allocated object, because it's not needed for resource and arena
allocated objects.

Also, added a GrowableArray destructor to call clear_and_deallocate() so that
all callers need to do is:
   GrowableArray<T> *ga = new (C_HEAP) GrowableArray<T>(,true);
   ...
   delete ga;  // call dtor and ResourceObj::operator delete()


Also I removed NonPrintingResourceObj because it's supposedly an optimization
of ResourceObj.  In PRODUCT mode, the virtual print() functions aren't
included anyway, so I didn't get the reason for the optimization.  Timed
runThese -full with fastdebug and it came out about the same, actually it
came out faster(?).

Also, fixed compilation warning from tagged stack interpreter putback.

Fix verified: y
Verified by:  Fixed asserts that were found with instances of Resource
              allocated growable arrays with C_heap elements.
              PRT

Other testing:  nsk vm.nightly.testlist (derived from vm.quick.testlist)
                  (include jvmti tests) with -client/-server
                runThese -full -client/-server

Initial version reviewed by: Steve B, Alan B, Ken, Mandy, Ramki, John R
Final version
Reviewed by: Steve B, John C, Steve G, Vladimir, Alan B
                                     
2005-09-07



Hardware and Software, Engineered to Work Together