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  @bug 7079260
  40  @summary XInputContext leaks memory by needRecetXXIClient field
  41  @author Petr Pchelko
  42  @library ../../regtesthelpers
  43  @build Util
  44  @compile InputContextMemoryLeakTest.java
  45  @run main/othervm -Xmx20M InputContextMemoryLeakTest
  46  */
  47 public class InputContextMemoryLeakTest {
  48 
  49     private static JFrame frame;
  50     private static WeakReference<JTextField> text;
  51     private static WeakReference<JPanel> p;
  52     private static JButton button;
  53 
  54     public static void init() throws Throwable {
  55         SwingUtilities.invokeAndWait(new Runnable() {
  56             @Override
  57             public void run() {
  58                 frame = new JFrame();
  59                 frame.setLayout(new FlowLayout());
  60                 JPanel p1 = new JPanel();
  61                 button = new JButton("Test");
  62                 p1.add(button);
  63                 frame.add(p1);
  64                 text = new WeakReference<JTextField>(new JTextField("Text"));
  65                 p = new WeakReference<JPanel>(new JPanel(new FlowLayout()));
  66                 p.get().add(text.get());
  67                 frame.add(p.get());
  68                 frame.setBounds(500, 400, 200, 200);
  69                 frame.setVisible(true);
  70             }
  71         });
  72 
  73         Util.focusComponent(text.get(), 500);
  74         Util.clickOnComp(button, new Robot());
  75         //References to objects testes for memory leak are stored in Util.
  76         //Need to clean them
  77         Util.cleanUp();
  78 
  79         SwingUtilities.invokeAndWait(new Runnable() {
  80             @Override
  81             public void run() {
  82                 frame.remove(p.get());  
  83             }
  84         });
  85         
  86         Util.waitForIdle(null);
  87         //After the next caret blink it automatically TextField references
  88         Thread.sleep(text.get().getCaret().getBlinkRate() * 2);
  89         Util.waitForIdle(null);
  90         assertGC();
  91     }
  92 
  93       public static void assertGC() throws Throwable {
  94         List<byte[]> alloc = new ArrayList<byte[]>();
  95         int size = 1024 * 10;
  96         while (true) {
  97             try {
  98                 alloc.add(new byte[size]);
  99             } catch (OutOfMemoryError err) {
 100                 break;
 101             }
 102         }
 103         alloc = null;
 104         if (text.get() != null) {
 105             throw new Exception("Test failed: JTextField was not collected");
 106         }
 107     }
 108 
 109     public static void main(String args[]) throws Throwable {
 110         init();
 111     }
 112 }