1 /*
   2  * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.
   8  *
   9  * This code is distributed in the hope that it will be useful, but WITHOUT
  10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  */
  23 
  24 import java.awt.FlowLayout;
  25 import java.awt.Robot;
  26 import java.lang.ref.Reference;
  27 import java.lang.ref.WeakReference;
  28 import java.util.ArrayList;
  29 import java.util.List;
  30 import javax.swing.JButton;
  31 import javax.swing.JFrame;
  32 import javax.swing.JPanel;
  33 import javax.swing.JTextField;
  34 import javax.swing.SwingUtilities;
  35 import test.java.awt.regtesthelpers.Util;
  36 
  37 /*
  38  @test
  39  @key headful
  40  @bug 7079260
  41  @summary XInputContext leaks memory by needRecetXXIClient field
  42  @author Petr Pchelko
  43  @library ../../regtesthelpers
  44  @build Util
  45  @compile InputContextMemoryLeakTest.java
  46  @run main/othervm -Xmx20M InputContextMemoryLeakTest
  47  */
  48 public class InputContextMemoryLeakTest {
  49 
  50     private static JFrame frame;
  51     private static WeakReference<JTextField> text;
  52     private static WeakReference<JPanel> p;
  53     private static JButton button;
  54 
  55     public static void init() throws Throwable {
  56         SwingUtilities.invokeAndWait(new Runnable() {
  57             @Override
  58             public void run() {
  59                 frame = new JFrame();
  60                 frame.setLayout(new FlowLayout());
  61                 JPanel p1 = new JPanel();
  62                 button = new JButton("Test");
  63                 p1.add(button);
  64                 frame.add(p1);
  65                 text = new WeakReference<JTextField>(new JTextField("Text"));
  66                 p = new WeakReference<JPanel>(new JPanel(new FlowLayout()));
  67                 p.get().add(text.get());
  68                 frame.add(p.get());
  69                 frame.setBounds(500, 400, 200, 200);
  70                 frame.setVisible(true);
  71             }
  72         });
  73 
  74         Util.focusComponent(text.get(), 500);
  75         Util.clickOnComp(button, new Robot());
  76         //References to objects testes for memory leak are stored in Util.
  77         //Need to clean them
  78         Util.cleanUp();
  79 
  80         SwingUtilities.invokeAndWait(new Runnable() {
  81             @Override
  82             public void run() {
  83                 frame.remove(p.get());
  84             }
  85         });
  86 
  87         Util.waitForIdle(null);
  88         //After the next caret blink it automatically TextField references
  89         Thread.sleep(text.get().getCaret().getBlinkRate() * 2);
  90         Util.waitForIdle(null);
  91         assertGC();
  92     }
  93 
  94       public static void assertGC() throws Throwable {
  95         List<byte[]> alloc = new ArrayList<byte[]>();
  96         int size = 1024 * 10;
  97         while (true) {
  98             try {
  99                 alloc.add(new byte[size]);
 100             } catch (OutOfMemoryError err) {
 101                 break;
 102             }
 103         }
 104         alloc = null;
 105         if (text.get() != null) {
 106             throw new Exception("Test failed: JTextField was not collected");
 107         }
 108     }
 109 
 110     public static void main(String args[]) throws Throwable {
 111         init();
 112     }
 113 }