# HG changeset patch # User arapte # Date 1470392317 -19800 # Node ID 5f77c9f089117389fea6871380ca0b5e23e1ef43 # Parent c776f49ac7e1a47d7cc0c4b9cccb13ae0c162dce 8039081: [TEST_BUG] Test java/awt/TrayIcon/PopupMenuLeakTest/PopupMenuLeakTest.java fails Reviewed-by: serb, psadhukhan diff -r c776f49ac7e1 -r 5f77c9f08911 jdk/src/java.desktop/share/classes/java/awt/TrayIcon.java --- a/jdk/src/java.desktop/share/classes/java/awt/TrayIcon.java Wed Aug 03 15:18:58 2016 +0800 +++ b/jdk/src/java.desktop/share/classes/java/awt/TrayIcon.java Fri Aug 05 15:48:37 2016 +0530 @@ -703,6 +703,9 @@ synchronized (this) { p = peer; peer = null; + if (popup != null) { + popup.removeNotify(); + } } if (p != null) { p.dispose(); diff -r c776f49ac7e1 -r 5f77c9f08911 jdk/src/java.desktop/unix/classes/sun/awt/X11/XTrayIconPeer.java --- a/jdk/src/java.desktop/unix/classes/sun/awt/X11/XTrayIconPeer.java Wed Aug 03 15:18:58 2016 +0800 +++ b/jdk/src/java.desktop/unix/classes/sun/awt/X11/XTrayIconPeer.java Fri Aug 05 15:48:37 2016 +0530 @@ -93,7 +93,6 @@ if (XWM.getWMID() != XWM.METACITY_WM) { parentXED = dummyXED; // We don't like to leave it 'null'. - } else { parentXED = new XEventDispatcher() { // It's executed under AWTLock. @@ -300,10 +299,19 @@ removeXED(getWindow(), eframeXED); removeXED(eframeParentID, parentXED); + removeListeners(); eframe.realDispose(); balloon.dispose(); + tooltip.dispose(); isTrayIconDisplayed = false; + canvas.dispose(); + canvas = null; + popup = null; + balloon = null; + tooltip = null; XToolkit.targetDisposedPeer(target, this); + target = null; + eframe = null; } public static void suppressWarningString(Window w) { @@ -416,6 +424,12 @@ eframe.addMouseListener(eventProxy); } + void removeListeners() { + canvas.removeMouseListener(eventProxy); + canvas.removeMouseMotionListener(eventProxy); + eframe.removeMouseListener(eventProxy); + } + long getWindow() { return AWTAccessor.getComponentAccessor() .getPeer(eframe).getWindow(); @@ -550,6 +564,11 @@ super.repaintImage(doClear || (old_autosize != autosize)); } + + public void dispose() { + super.dispose(); + target = null; + } } @SuppressWarnings("serial") // JDK-implementation class @@ -573,6 +592,10 @@ repaintImage(true); } + public void dispose() { + observer = null; + } + // Invoke on EDT. protected void repaintImage(boolean doClear) { Graphics g = getGraphics(); diff -r c776f49ac7e1 -r 5f77c9f08911 jdk/test/java/awt/TrayIcon/PopupMenuLeakTest/PopupMenuLeakTest.java --- a/jdk/test/java/awt/TrayIcon/PopupMenuLeakTest/PopupMenuLeakTest.java Wed Aug 03 15:18:58 2016 +0800 +++ b/jdk/test/java/awt/TrayIcon/PopupMenuLeakTest/PopupMenuLeakTest.java Fri Aug 05 15:48:37 2016 +0530 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,17 +22,25 @@ */ /* - @test - @key headful - @bug 8007220 - @summary Reference to the popup leaks after the TrayIcon is removed - @author Petr Pchelko + @test + @key headful + @bug 8007220 8039081 + @summary Reference to the popup leaks after the TrayIcon is removed. + @requires os.family != "windows" @library ../../../../lib/testlibrary/ @build ExtendedRobot @run main/othervm -Xmx50m PopupMenuLeakTest */ -import java.awt.*; +import java.awt.AWTException; +import java.awt.Color; +import java.awt.Graphics2D; +import java.awt.Image; +import java.awt.MenuItem; +import java.awt.PopupMenu; +import java.awt.RenderingHints; +import java.awt.SystemTray; +import java.awt.TrayIcon; import javax.swing.SwingUtilities; import java.awt.image.BufferedImage; @@ -45,7 +53,6 @@ static final AtomicReference> iconWeakReference = new AtomicReference<>(); static final AtomicReference> popupWeakReference = new AtomicReference<>(); static ExtendedRobot robot; - public static void main(String[] args) throws Exception { robot = new ExtendedRobot(); SwingUtilities.invokeAndWait(PopupMenuLeakTest::createSystemTrayIcon); @@ -55,8 +62,8 @@ sleep(); SwingUtilities.invokeAndWait(PopupMenuLeakTest::removeIcon); sleep(); + assertCollected(iconWeakReference.get(), "Failed, reference to tray icon not collected"); assertCollected(popupWeakReference.get(), "Failed, reference to popup not collected"); - assertCollected(iconWeakReference.get(), "Failed, reference to tray icon not collected"); } private static void addNotifyPopup() { @@ -78,12 +85,17 @@ private static void assertCollected(WeakReference reference, String message) { java.util.List bytes = new ArrayList<>(); for (int i = 0; i < 5; i ++) { + if (reference.get() == null) { + // reference is collected, avoid OOMs. + break; + } try { while (true) { - bytes.add(new byte[1024]); + bytes.add(new byte[4096]); } } catch (OutOfMemoryError err) { - bytes = new ArrayList<>(); + bytes.clear(); + causeGC(); } } if (reference.get() != null) { @@ -91,6 +103,13 @@ } } + private static void causeGC() { + System.gc(); + System.runFinalization(); + robot.delay(1000); + } + + private static void createSystemTrayIcon() { final TrayIcon trayIcon = new TrayIcon(createTrayIconImage()); trayIcon.setImageAutoSize(true);