Path: blob/master/test/jdk/javax/swing/JMenu/PopupReferenceMemoryLeak.java
41149 views
/*1* Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation.7*8* This code is distributed in the hope that it will be useful, but WITHOUT9* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or10* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License11* version 2 for more details (a copy is included in the LICENSE file that12* accompanied this code).13*14* You should have received a copy of the GNU General Public License version15* 2 along with this work; if not, write to the Free Software Foundation,16* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.17*18* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA19* or visit www.oracle.com if you need additional information or have any20* questions.21*/2223/*24* @test25* @bug 490779826* @key headful27* @summary Check for memory leak in menu subsystem28* @run main/othervm -Xmx8m PopupReferenceMemoryLeak29*/3031import javax.swing.AbstractAction;32import javax.swing.JFrame;33import javax.swing.JMenu;34import javax.swing.JMenuBar;35import javax.swing.JMenuItem;36import javax.swing.SwingUtilities;37import javax.swing.UIManager;38import javax.swing.UnsupportedLookAndFeelException;39import javax.swing.WindowConstants;40import java.awt.BorderLayout;41import java.awt.Robot;42import java.awt.event.ActionEvent;43import java.awt.event.InputEvent;44import java.awt.event.KeyEvent;45import java.lang.ref.WeakReference;46import java.util.ArrayList;4748import static javax.swing.UIManager.getInstalledLookAndFeels;4950public class PopupReferenceMemoryLeak {51static volatile WeakReference referenceToFrame1;52static JFrame frame1, frame2;5354public static void main(String[] args) throws Exception {55Robot robot = new Robot();56robot.setAutoDelay(200);57for (UIManager.LookAndFeelInfo laf : getInstalledLookAndFeels()) {58String lafName = laf.getName();59System.out.println("Testing LaF: " + lafName);60if (lafName == null || lafName.startsWith("Mac OS X")) {61// Aqua Look and Feel uses system menus we can't really test it62continue;63}64setLookAndFeel(laf);65PopupReferenceMemoryLeak newTest = new PopupReferenceMemoryLeak();66SwingUtilities.invokeAndWait(newTest::createUI);67try {68boolean passed = false;69robot.waitForIdle();70Thread.sleep(2000);71robot.mouseMove(200, 200);72robot.mousePress(InputEvent.BUTTON1_DOWN_MASK);73robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK);74robot.keyPress(KeyEvent.VK_F10);75robot.keyRelease(KeyEvent.VK_F10);76robot.keyPress(KeyEvent.VK_F);77robot.keyRelease(KeyEvent.VK_F);78robot.keyPress(KeyEvent.VK_C);79robot.keyRelease(KeyEvent.VK_C);80robot.waitForIdle();81Thread.sleep(2000);82robot.mouseMove(600, 200);83robot.waitForIdle();84Thread.sleep(2000);85robot.mousePress(InputEvent.BUTTON1_DOWN_MASK);86robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK);8788// Workaround for Linux issues when sometimes there89// is a ref to last opened frame from native code90JFrame frame3 = new JFrame("Workaround");91frame3.setSize(100, 100);92frame3.setLocation(0,0);93frame3.setVisible(true);94Thread.sleep(1000);95frame3.setVisible(false);96frame3.dispose();9798// Force GC three times to see if it clears the old frame99for (int i = 0; i < 3; i++) {100try {101ArrayList gc = new ArrayList();102while (true) {103gc.add(new int[100000]);104}105} catch (Throwable ignore) {106}107robot.waitForIdle();108Thread.sleep(1000);109if (referenceToFrame1.get() == null) {110// Frame was released111passed = true;112break;113}114}115if (!passed) {116robot.waitForIdle();117robot.keyPress(KeyEvent.VK_F10);118robot.keyRelease(KeyEvent.VK_F10);119robot.keyPress(KeyEvent.VK_T);120robot.keyRelease(KeyEvent.VK_T);121robot.keyPress(KeyEvent.VK_M);122robot.keyRelease(KeyEvent.VK_M);123robot.waitForIdle();124Thread.sleep(2000);125for (int i = 0; i < 5; i++) {126try {127ArrayList gc = new ArrayList();128while (true) {129gc.add(new int[100000]);130}131} catch (Throwable ignore) {132}133robot.waitForIdle();134Thread.sleep(1000);135if (referenceToFrame1.get() == null) {136// Frame was released137throw new RuntimeException("Frame cleared only after menu activated on frame2");138}139}140throw new RuntimeException("Test finished but menu has not cleared the reference!");141}142} catch (Exception re) {143throw new RuntimeException(re.getLocalizedMessage());144} finally {145if (frame2 != null) {146frame2.setVisible(false);147frame2.dispose();148}149}150}151}152153private static void setLookAndFeel(UIManager.LookAndFeelInfo laf) {154try {155UIManager.setLookAndFeel(laf.getClassName());156} catch (UnsupportedLookAndFeelException ignored) {157System.out.println("Unsupported LookAndFeel: " + laf.getClassName());158} catch (Exception e) {159throw new RuntimeException(e);160}161}162163164public void createUI() {165frame1 = new JFrame("Main test window");166JMenuBar menuBar1 = new JMenuBar();167JMenu file1 = new JMenu("File");168file1.setMnemonic('f');169JMenuItem close1 = new JMenuItem("Close");170close1.setMnemonic('c');171close1.addActionListener(new FrameCloser(frame1));172file1.add(close1);173menuBar1.add(file1);174frame1.setJMenuBar(menuBar1);175frame1.setSize(200, 200);176frame1.setLocation(100, 100);177frame1.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);178frame1.setVisible(true);179referenceToFrame1 = new WeakReference(frame1);180frame1 = null;181182frame2 = new JFrame("Secondary");183JMenuBar menuBar2 = new JMenuBar();184JMenu test = new JMenu("Test");185test.setMnemonic('T');186JMenuItem memoryTest = new JMenuItem("Memory");187memoryTest.setMnemonic('M');188test.add(memoryTest);189menuBar2.add(test);190frame2.setJMenuBar(menuBar2);191frame2.setLayout(new BorderLayout());192frame2.setSize(200, 200);193frame2.setLocation(500, 100);194frame2.setVisible(true);195}196197class FrameCloser extends AbstractAction {198JFrame frame;199public FrameCloser(JFrame f) {200this.frame = f;201}202203@Override204public void actionPerformed(ActionEvent e) {205if (frame != null) {206frame.setVisible(false);207frame.dispose();208this.frame = null;209}210}211}212}213214215