<AWT Dev> Best workaround for OSX Window leak? (JDK-8029147)

Andy Lee andy.ja.lee at gmail.com
Tue Sep 20 17:44:22 UTC 2016


Ah, now that is interesting...  I was actually closing the JFrames manually
by clicking the close button on the upper left corner of each window that
appeared (and since I set the default close operation to DISPOSE_ON_CLOSE,
this resulted in dispose() being called on each frame).

Indeed, using your modification to programmatically call dispose() allows
the JFrames to be properly GC'd in 8u112.  This is strange because I
confirmed that dispose was actually being called when I manually closed the
windows using the window decoration, so somehow the close button must be
doing something slightly different that is still causing the JFrames to
leak.

I modified my test case to do additional testing and discovered another odd
detail.  If you move the JFrame (by dragging its title bar with your mouse)
before disposing it via a manual call to dispose(), it also causes the
JFrame to leak.

Here's a link to my updated test case (basically just added buttons for
testing the different scenarios):
http://bonuslord.github.io/misc/FrameLeakDemo2.java

There seem to be 3 primary cases (I performed all testing on JDK 8u112):
1. Dispose all frames by clicking the 'Dispose Forever' button. Result: No
leak
2. Dispose all frames by using the window decoration. Result: All frames
leak
3. Move all of the frames by dragging on the title bar, then dispose using
the 'Dispose Forever' button. Result: All frames leak

I'm guessing case 2 and case 3 may have the same underlying cause since
both involve interacting with the native window title bar?

On Tue, Sep 20, 2016 at 12:44 PM, Sergey Bylokhov <
Sergey.Bylokhov at oracle.com> wrote:

> Hi, Andy.
> You code lack of Frame.dispose(), so the frames are shown forever. You can
> update the test by these lines:
>         frm.setVisible(true);
> +        try {
> +            Thread.sleep(1000);
> +        } catch (InterruptedException e) {
> +            e.printStackTrace();
> +        }
> +        frm.dispose();
>
> And it will pass after some period of time on jdk8u112, and fails on
> jdk8u101. Can you please double check?
>
> On 20.09.16 15:43, Andy Lee wrote:
>
>> Here is my test code that demonstrates the
>> leak: http://bonuslord.github.io/misc/FrameLeakDemo.java
>>
>> In JDK 8 the output indicates 3 frames remaining even after closing all
>> of the JFrames.
>> In JDK 9 the output usually reports 1 frame remaining after closing all
>> of the frames, although sometimes all 3 JFrames get properly GC'd and
>> the output reports 0.
>>
>> On Mon, Sep 19, 2016 at 4:08 PM, Sergey Bylokhov
>> <Sergey.Bylokhov at oracle.com <mailto:Sergey.Bylokhov at oracle.com>> wrote:
>>
>>     On 19.09.16 23:02, Andy Lee wrote:
>>
>>         In JDK 9 the problem seems to be partially fixed; only the most
>>         recently
>>         closed JFrame leaks (ie, a temporary leak).  I was unable to get
>>         Visual
>>         VM to connect to the Java 9 process so I'm not exactly sure what
>> was
>>         preventing the last JFrame from being GC'd.
>>
>>
>>     Can you place the code which uses JFrame somewhere? It seems that
>>     some of the related bugs were not backported, like:
>>     https://bugs.openjdk.java.net/browse/JDK-8156116
>>     <https://bugs.openjdk.java.net/browse/JDK-8156116>
>>
>>     I will check which one.
>>
>>
>>         The Java 9 behavior would be sufficient to solve most of our major
>>         issues, but it will be quite some time before it becomes feasible
>> to
>>         move our application to Java 9 so it doesn't really help us.
>>
>>         On Mon, Sep 19, 2016 at 2:51 PM, Sergey Bylokhov
>>         <Sergey.Bylokhov at oracle.com <mailto:Sergey.Bylokhov at oracle.com>
>>         <mailto:Sergey.Bylokhov at oracle.com
>>         <mailto:Sergey.Bylokhov at oracle.com>>> wrote:
>>
>>             On 19.09.16 19:13, Andy Lee wrote:
>>
>>                 Yes, I just tried my test case on JDK 8u112 and I can
>> still
>>                 reproduce
>>                 the JFrame leak.
>>
>>
>>             And what about the latest jdk9?
>>             https://jdk9.java.net/download
>>
>>
>>                 On Mon, Sep 19, 2016 at 11:26 AM, Sergey Bylokhov
>>                 <Sergey.Bylokhov at oracle.com
>>         <mailto:Sergey.Bylokhov at oracle.com>
>>         <mailto:Sergey.Bylokhov at oracle.com
>>         <mailto:Sergey.Bylokhov at oracle.com>>
>>                 <mailto:Sergey.Bylokhov at oracle.com
>>         <mailto:Sergey.Bylokhov at oracle.com>
>>
>>                 <mailto:Sergey.Bylokhov at oracle.com
>>         <mailto:Sergey.Bylokhov at oracle.com>>>> wrote:
>>
>>                     Hi, Andy.
>>                     I suggest to check the latest jdk9 and jdk8. Do you
>>         able to
>>                     reproduce this bug on jdk8u112?
>>
>>
>>                     On 19.09.16 17:19, Andy Lee wrote:
>>
>>                         Not sure if this is the best place to ask, but I'm
>>                 looking for
>>                         good way
>>                         to prevent the JFrame/JDialog memory leaks caused
>>                         by
>>         https://bugs.openjdk.java.net/browse/JDK-8029147
>>         <https://bugs.openjdk.java.net/browse/JDK-8029147>
>>                 <https://bugs.openjdk.java.net/browse/JDK-8029147
>>         <https://bugs.openjdk.java.net/browse/JDK-8029147>>
>>
>>         <https://bugs.openjdk.java.net/browse/JDK-8029147
>>         <https://bugs.openjdk.java.net/browse/JDK-8029147>
>>                 <https://bugs.openjdk.java.net/browse/JDK-8029147
>>         <https://bugs.openjdk.java.net/browse/JDK-8029147>>>
>>
>>                         The best solution I've found so far is to use
>>         reflection
>>                 to dig
>>                         in and
>>                         null out the 'target' fields on the
>>         LWComponentPeer and
>>                         CPlatformWindow
>>                         after disposing.  This at least allows the
>>         JDialog/JFrame
>>                         instance to be
>>                         GC'd (along with any heavier objects they may
>>                 reference), but isn't
>>                         optimal since ultimately the LWComponentPeer and
>>                 CPlatformWindow
>>                         instances still end up leaking.  Another problem
>>         with this
>>                         approach is
>>                         that we have hundreds of uses of
>>         JFrames/JDialogs across our
>>                         codebase
>>                         and this workaround would require each one of
>>         them to be
>>                         modified to add
>>                         this special cleanup logic; I'd like to avoid
>>         that if at all
>>                         possible~
>>
>>                         Any suggestions?
>>
>>                         ~Andy Lee
>>
>>
>>
>>                     --
>>                     Best regards, Sergey.
>>
>>
>>
>>
>>             --
>>             Best regards, Sergey.
>>
>>
>>
>>
>>     --
>>     Best regards, Sergey.
>>
>>
>>
>
> --
> Best regards, Sergey.
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.openjdk.java.net/pipermail/awt-dev/attachments/20160920/09180d0e/attachment.html>


More information about the awt-dev mailing list