提交 f72729f5 编写于 作者: S serb

8041654: OutOfMemoryError: RepaintManager doesn't clean up cache of volatile images

Reviewed-by: azvegint, ant
上级 f9520d17
...@@ -181,9 +181,16 @@ public class RepaintManager ...@@ -181,9 +181,16 @@ public class RepaintManager
*/ */
private final ProcessingRunnable processingRunnable; private final ProcessingRunnable processingRunnable;
private final static JavaSecurityAccess javaSecurityAccess = private static final JavaSecurityAccess javaSecurityAccess =
SharedSecrets.getJavaSecurityAccess(); SharedSecrets.getJavaSecurityAccess();
/**
* Listener installed to detect display changes. When display changes,
* schedules a callback to notify all RepaintManagers of the display
* changes.
*/
private static final DisplayChangedListener displayChangedHandler =
new DisplayChangedHandler();
static { static {
SwingAccessor.setRepaintManagerAccessor(new SwingAccessor.RepaintManagerAccessor() { SwingAccessor.setRepaintManagerAccessor(new SwingAccessor.RepaintManagerAccessor() {
...@@ -225,8 +232,8 @@ public class RepaintManager ...@@ -225,8 +232,8 @@ public class RepaintManager
GraphicsEnvironment ge = GraphicsEnvironment. GraphicsEnvironment ge = GraphicsEnvironment.
getLocalGraphicsEnvironment(); getLocalGraphicsEnvironment();
if (ge instanceof SunGraphicsEnvironment) { if (ge instanceof SunGraphicsEnvironment) {
((SunGraphicsEnvironment)ge).addDisplayChangedListener( ((SunGraphicsEnvironment) ge).addDisplayChangedListener(
new DisplayChangedHandler()); displayChangedHandler);
} }
Toolkit tk = Toolkit.getDefaultToolkit(); Toolkit tk = Toolkit.getDefaultToolkit();
if ((tk instanceof SunToolkit) if ((tk instanceof SunToolkit)
...@@ -1649,6 +1656,12 @@ public class RepaintManager ...@@ -1649,6 +1656,12 @@ public class RepaintManager
*/ */
private static final class DisplayChangedHandler implements private static final class DisplayChangedHandler implements
DisplayChangedListener { DisplayChangedListener {
// Empty non private constructor was added because access to this
// class shouldn't be generated by the compiler using synthetic
// accessor method
DisplayChangedHandler() {
}
public void displayChanged() { public void displayChanged() {
scheduleDisplayChanges(); scheduleDisplayChanges();
} }
...@@ -1656,11 +1669,10 @@ public class RepaintManager ...@@ -1656,11 +1669,10 @@ public class RepaintManager
public void paletteChanged() { public void paletteChanged() {
} }
private void scheduleDisplayChanges() { private static void scheduleDisplayChanges() {
// To avoid threading problems, we notify each RepaintManager // To avoid threading problems, we notify each RepaintManager
// on the thread it was created on. // on the thread it was created on.
for (Object c : AppContext.getAppContexts()) { for (AppContext context : AppContext.getAppContexts()) {
AppContext context = (AppContext) c;
synchronized(context) { synchronized(context) {
if (!context.isDisposed()) { if (!context.isDisposed()) {
EventQueue eventQueue = (EventQueue)context.get( EventQueue eventQueue = (EventQueue)context.get(
......
...@@ -598,14 +598,19 @@ public final class XToolkit extends UNIXToolkit implements Runnable { ...@@ -598,14 +598,19 @@ public final class XToolkit extends UNIXToolkit implements Runnable {
} }
} }
} }
if( keyEventLog.isLoggable(PlatformLogger.Level.FINE) && (ev.get_type() == XConstants.KeyPress || ev.get_type() == XConstants.KeyRelease) ) { if (keyEventLog.isLoggable(PlatformLogger.Level.FINE) && (
keyEventLog.fine("before XFilterEvent:"+ev); ev.get_type() == XConstants.KeyPress
|| ev.get_type() == XConstants.KeyRelease)) {
keyEventLog.fine("before XFilterEvent:" + ev);
} }
if (XlibWrapper.XFilterEvent(ev.getPData(), w)) { if (XlibWrapper.XFilterEvent(ev.getPData(), w)) {
continue; continue;
} }
if( keyEventLog.isLoggable(PlatformLogger.Level.FINE) && (ev.get_type() == XConstants.KeyPress || ev.get_type() == XConstants.KeyRelease) ) { if (keyEventLog.isLoggable(PlatformLogger.Level.FINE) && (
keyEventLog.fine("after XFilterEvent:"+ev); // IS THIS CORRECT? ev.get_type() == XConstants.KeyPress
|| ev.get_type() == XConstants.KeyRelease)) {
keyEventLog.fine(
"after XFilterEvent:" + ev); // IS THIS CORRECT?
} }
dispatchEvent(ev); dispatchEvent(ev);
...@@ -621,21 +626,28 @@ public final class XToolkit extends UNIXToolkit implements Runnable { ...@@ -621,21 +626,28 @@ public final class XToolkit extends UNIXToolkit implements Runnable {
} }
} }
/**
* Listener installed to detect display changes.
*/
private static final DisplayChangedListener displayChangedHandler =
new DisplayChangedListener() {
@Override
public void displayChanged() {
// 7045370: Reset the cached values
XToolkit.screenWidth = -1;
XToolkit.screenHeight = -1;
}
@Override
public void paletteChanged() {
}
};
static { static {
GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment(); GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
if (ge instanceof SunGraphicsEnvironment) { if (ge instanceof SunGraphicsEnvironment) {
((SunGraphicsEnvironment)ge).addDisplayChangedListener( ((SunGraphicsEnvironment) ge).addDisplayChangedListener(
new DisplayChangedListener() { displayChangedHandler);
@Override
public void displayChanged() {
// 7045370: Reset the cached values
XToolkit.screenWidth = -1;
XToolkit.screenHeight = -1;
}
@Override
public void paletteChanged() {}
});
} }
} }
...@@ -645,7 +657,9 @@ public final class XToolkit extends UNIXToolkit implements Runnable { ...@@ -645,7 +657,9 @@ public final class XToolkit extends UNIXToolkit implements Runnable {
try { try {
XWindowAttributes pattr = new XWindowAttributes(); XWindowAttributes pattr = new XWindowAttributes();
try { try {
XlibWrapper.XGetWindowAttributes(XToolkit.getDisplay(), XToolkit.getDefaultRootWindow(), pattr.pData); XlibWrapper.XGetWindowAttributes(XToolkit.getDisplay(),
XToolkit.getDefaultRootWindow(),
pattr.pData);
screenWidth = (int) pattr.get_width(); screenWidth = (int) pattr.get_width();
screenHeight = (int) pattr.get_height(); screenHeight = (int) pattr.get_height();
} finally { } finally {
......
/*
* Copyright (c) 2015, 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
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.GraphicsEnvironment;
import javax.swing.JFrame;
import javax.swing.JLabel;
import sun.java2d.SunGraphicsEnvironment;
/**
* @test
* @bug 8041654
* @run main/othervm -Xmx80m DisplayListenerLeak
*/
public final class DisplayListenerLeak {
private static JFrame frame;
private volatile static boolean failed = false;
private static void createAndShowGUI() {
Thread.currentThread().setUncaughtExceptionHandler((t, e) -> {
e.printStackTrace();
failed = true;
});
frame = new JFrame();
JLabel emptyLabel = new JLabel("");
emptyLabel.setPreferredSize(new Dimension(600, 400));
frame.getContentPane().add(emptyLabel, BorderLayout.CENTER);
frame.pack();
frame.setVisible(true);
}
public static void main(final String[] args) throws Exception {
GraphicsEnvironment ge =
GraphicsEnvironment.getLocalGraphicsEnvironment();
if (!(ge instanceof SunGraphicsEnvironment)) {
return;
}
EventQueue.invokeAndWait(() -> createAndShowGUI());
SunGraphicsEnvironment sge = (SunGraphicsEnvironment) ge;
final long startTime = System.nanoTime();
while (!failed) {
if (System.nanoTime() - startTime > 60_000_000_000L) {
break;
}
System.gc(); // clear all weak references
EventQueue.invokeAndWait(() -> {
frame.setSize(frame.getHeight(), frame.getWidth());
frame.pack();
});
EventQueue.invokeAndWait(sge::displayChanged);
}
EventQueue.invokeAndWait(frame::dispose);
if (failed) {
throw new RuntimeException();
}
}
}
\ No newline at end of file
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册