Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-4858370

JDWP: Memory Leak: GlobalRefs never deleted when processing invokeMethod command

    Details

    • Type: Bug
    • Status: Closed
    • Priority: P4
    • Resolution: Fixed
    • Affects Version/s: 1.4.1, 8u74, 9
    • Fix Version/s: 9
    • Component/s: core-svc
    • Subcomponent:
    • Resolved In Build:
      b115
    • CPU:
      x86
    • OS:
      linux
    • Verification:
      Fix failed

      Backports

        Description



        Name: tb29552 Date: 05/05/2003


        FULL PRODUCT VERSION :
        java version "1.4.1_02"

        Java(TM) 2 Runtime Environment, Standard Edition (build 1.4.1_02-b06)

        Java HotSpot(TM) Client VM (build 1.4.1_02-b06, mixed mode)


        FULL OS VERSION :
        Linux boulette 2.4.19-k7 #1 Tue Nov 19 03:01:13 EST 2002 i686 unknown unknown GNU/Linux

        A DESCRIPTION OF THE PROBLEM :
        When a method is to be called in the target JVM by the mean of the JDWP command "invokeMethod" (accessed for example with the "print" feature in jdb), the implementation of JDWP (on any platform) makes global references for every Object that is implied in the method invocation: Thread that executes the call, Class that contains the method to call (eventually Instance in which the method will be called) and method arguments which type is Object. This is done in fillInvokeRequest() in file j2se/src/share/back/invoker.c.

        When the method invocation terminates, global references are also created for the returned argument (if it is an Object) and for Exception that might have been thrown.

        These global refs are created to be sure that objects implied in the invocation will not be collected by the GC until the JDWP command is fully processed.



        When the result of the invocation is to be returned by JDWP, the global reference for the exception is deleted (at function invoker_completeInvokeRequest() in file j2se/src/share/back/invoker.c). A globalref retained for the execution thread is deleted too (at handleReportInvokeDoneCommand() in file j2se/src/share/back/eventHelper).



        At this time, the request is fully processed but globalreferences created for arguments are never deleted, which is an very annoying memory leak.



        A clean way to fix this memory leak is to modify function invoker_completeInvokeRequest() as followed:

        void

        invoker_completeInvokeRequest(jthread thread)

        {

            // the beginning of the function stays the same.

            // I only added code to its end.

            ...

            ...

            ...



            if (!detached) {

                outStream_initReply(&out, id);

                outStream_writeValue(env, &out, tag, returnValue);

                outStream_writeObjectTag(&out, exc);

                WRITE_GLOBAL_REF(env, &out, exc);

                outStream_sendReply(&out);

            }



            // here comes the change...

            /*

             * At this time, there's no need to retain global references on

             * arguments since the reply is processed. No one will deal with

             * this request ID anymore, so we must call deleteGlobalRef().

             */

            deleteGlobalRefs(env, request);

            if ((request->invokeType == INVOKE_CONSTRUCTOR) ||

        (returnTypeTag(request->methodSignature) == JDWP_Tag_OBJECT)) {

              (*env)->DeleteGlobalRef(env, request->returnValue.l);

            }

        }




        STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
        When using jdb and that the debuggee is suspended in method foo(Object bar), just type "print bar.toString()" to trigger the JDWP command "invokeMethod".

        The problem can also be reproduced with jdk 1.4.2-beta




        EXPECTED VERSUS ACTUAL BEHAVIOR :
        EXPECTED -
        GlobalRefs created during the process of the command should all be deleted. This must be done here because they cannot be freed later by any other agent (such as a custom debugger or custom profiler) started in the target JVM.

        ACTUAL -
        GlobalRefs created for arguments of the method invocation are never deleted. This is responsible of an horrible memory leak !

        My custom debugger/profiler uses JDWP to invoke a custom method in the target JVM that will request JVMPI heap dump to know every alive objects that are referencing a particular JVM Object. Because of this memory leak, my debugger always return wrong informations, i.e it reports GlobalRefs on Objects while actually no GlobalRef has been allocated by the debugged program itself :(


        ERROR MESSAGES/STACK TRACES THAT OCCUR :
        (no error displayed on screen)

        REPRODUCIBILITY :
        This bug can be reproduced always.

        ---------- BEGIN SOURCE ----------
        public class incoming2 {

            public static void main(String[] args) {

                // break into main and do "print c1.toString()" in jdb

        Class c1=Object.class;

        System.out.println("1st: "+c1);

            }

        }



        ---------- END SOURCE ----------

        CUSTOMER SUBMITTED WORKAROUND :
        This should really be fixed in JVM-side, since it's JDWP that is responsible of the allocation of the GlobalRefs.
        (Review ID: 185252)
        ======================================================================

          Issue Links

            Activity

            Hide
            tbell Tim Bell added a comment -
            BT2:EVALUATION


            ###@###.### 2003-05-05

            In this case there needs to be automatic cleanup/GC of global
            resources allocated. But see also bug 4257193, which is a request
            for more explicit control over the lifetime of Objects created
            in the debugee VM on behalf of the debugger.

            ###@###.### 2003-05-06

            Committing to the same release as 4257193. These bugfixes
            will be considered together.
            Show
            tbell Tim Bell added a comment - BT2:EVALUATION ###@###.### 2003-05-05 In this case there needs to be automatic cleanup/GC of global resources allocated. But see also bug 4257193, which is a request for more explicit control over the lifetime of Objects created in the debugee VM on behalf of the debugger. ###@###.### 2003-05-06 Committing to the same release as 4257193. These bugfixes will be considered together.
            Hide
            defectconv Defect Conversion BT2 (Inactive) added a comment -
            BT2:PUBLIC COMMENTS

            .
            Show
            defectconv Defect Conversion BT2 (Inactive) added a comment - BT2:PUBLIC COMMENTS .
            Show
            sgehwolf Severin Gehwolf added a comment - Posted patch for review: http://mail.openjdk.java.net/pipermail/serviceability-dev/2016-March/019155.html
            Hide
            hgupdate HG Updates added a comment -
            URL: http://hg.openjdk.java.net/jdk9/hs-rt/jdk/rev/277d7584fa03
            User: sspitsyn
            Date: 2016-03-22 23:15:22 +0000
            Show
            hgupdate HG Updates added a comment - URL: http://hg.openjdk.java.net/jdk9/hs-rt/jdk/rev/277d7584fa03 User: sspitsyn Date: 2016-03-22 23:15:22 +0000
            Hide
            dcubed Daniel Daugherty added a comment -
            This fix and test was backed out in JDK9-hs-rt via: JDK-8153673
            Show
            dcubed Daniel Daugherty added a comment - This fix and test was backed out in JDK9-hs-rt via: JDK-8153673
            Hide
            dcubed Daniel Daugherty added a comment -
            This fix caused some test regressions and was backed out
            of JDK9-hs-rt using the following:

            JDK-8153673 [BACKOUT] JDWP: Memory Leak: GlobalRefs never deleted when processing invokeMethod command
            Show
            dcubed Daniel Daugherty added a comment - This fix caused some test regressions and was backed out of JDK9-hs-rt using the following: JDK-8153673 [BACKOUT] JDWP: Memory Leak: GlobalRefs never deleted when processing invokeMethod command
            Hide
            hgupdate HG Updates added a comment -
            URL: http://hg.openjdk.java.net/jdk9/jdk9/jdk/rev/277d7584fa03
            User: lana
            Date: 2016-04-20 17:52:51 +0000
            Show
            hgupdate HG Updates added a comment - URL: http://hg.openjdk.java.net/jdk9/jdk9/jdk/rev/277d7584fa03 User: lana Date: 2016-04-20 17:52:51 +0000

              People

              • Assignee:
                sgehwolf Severin Gehwolf
                Reporter:
                tbell Tim Bell
              • Votes:
                0 Vote for this issue
                Watchers:
                3 Start watching this issue

                Dates

                • Created:
                  Updated:
                  Resolved:
                  Imported:
                  Indexed: