Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-5085626

Exponential performance regression in AWT components (multiple monitors)

XMLWordPrintable

    • 06
    • x86
    • windows_xp

        Name: rmT116609 Date: 08/11/2004


        FULL PRODUCT VERSION :
        java version "1.5.0-beta2"
        Java(TM) 2 Runtime Environment, Standard Edition (build 1.5.0-beta2-b51)
        Java HotSpot(TM) Client VM (build 1.5.0-beta2-b51, mixed mode, sharing)

        *BUT*

        This occurs for any JDK 1.4+

        ADDITIONAL OS VERSION INFORMATION :
        Windows XP
        Windows (Any)

        EXTRA RELEVANT SYSTEM CONFIGURATION :
        My video setup is two NEC MultiSync LCD 1980SX monitors using
        an NVIDIA Quadro NVS graphics card, though this problem would occur in any multi monitor environment.

        A DESCRIPTION OF THE PROBLEM :
        import java.awt.Frame;
        import java.awt.Label;
        import java.awt.event.WindowAdapter;
        import java.awt.event.WindowEvent;
        import java.awt.Button;
        import java.awt.BorderLayout;
        import java.awt.Panel;
        import javax.swing.JFrame;
        import javax.swing.JLabel;
        import javax.swing.JPanel;

        /**
         * Instructions:
         *
         * The following snippet demonstrates a severe performance regression in AWT
         * starting in 1.4 (merlin), and still present in the current version of the JDK
         * (tiger beta 2). In a multimonitor Windows XP environment set up as a single
         * display area (my video setup is two NEC MultiSync LCD 1980SX monitors using
         * an NVIDIA Quadro NVS graphics card), take the window and drag it rapidly
         * between the two monitors. In the AWT program, the event dispatch thread is
         * frozen while all of the surface datas are being recreated in the hierarchy
         * (in Win32SurfaceData.initOps). Note that the Swing program does not exhibit
         * the behavior because it does not have native peers.
         */
        public class Test {

            private static final int NESTED_PANELS = 25;

            // This one is very slow!
            public static void testAWT() {
                Frame frame = new Frame("AWT Test");
                frame.addWindowListener(new WindowAdapter() {
                    public void windowClosing(WindowEvent ev) {
                        System.exit(0);
                    }
                });
                frame.setLayout(new BorderLayout());
                Label label = new Label("Hello world");
                frame.add(label, BorderLayout.NORTH);
                Panel panel = new Panel(new BorderLayout());
                Panel currentPanel = panel;
                for (int i = 0; i < NESTED_PANELS; i++) {
                    Panel newPanel = new Panel(new BorderLayout());
                    currentPanel.add(newPanel, BorderLayout.CENTER);
                    currentPanel = newPanel;
                }
                currentPanel.add(new Label("Test"));
                frame.add(panel, BorderLayout.CENTER);
                Button btn = new Button("OK");
                frame.add(btn, BorderLayout.SOUTH);
                frame.pack();
                frame.setVisible(true);
            }

            // This one works swell!
            public static void testSwing() {
                JFrame frame = new JFrame("Swing Test");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.getContentPane().setLayout(new BorderLayout());
                JLabel label = new JLabel("Hello world");
                frame.getContentPane().add(label, BorderLayout.NORTH);
                JPanel panel = new JPanel(new BorderLayout());
                JPanel currentPanel = panel;
                for (int i = 0; i < NESTED_PANELS; i++) {
                    JPanel newPanel = new JPanel(new BorderLayout());
                    currentPanel.add(newPanel, BorderLayout.CENTER);
                    currentPanel = newPanel;
                }
                currentPanel.add(new Label("Test"));
                frame.getContentPane().add(panel, BorderLayout.CENTER);
                Button btn = new Button("OK");
                frame.getContentPane().add(btn, BorderLayout.SOUTH);
                frame.pack();
                frame.setVisible(true);
            }

            public static void main(String[] args) {
                testAWT();
                // testSwing();
            }
        }


        STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
        See the above code snippet documentation. Drag the window from one monitor to the other. Try to press the button.

        EXPECTED VERSUS ACTUAL BEHAVIOR :
        EXPECTED -
        See the Swing version for bug-free behavior.
        ACTUAL -
        Exponential performance degredation depending on number of levels in the component hierarchy.

        ERROR MESSAGES/STACK TRACES THAT OCCUR :
        Stuck in Win32SurfaceData.initOps for all of the components while it exponentially goes through the hierarchy.

        REPRODUCIBILITY :
        This bug can be reproduced always.

        ---------- BEGIN SOURCE ----------
        import java.awt.Frame;
        import java.awt.Label;
        import java.awt.event.WindowAdapter;
        import java.awt.event.WindowEvent;
        import java.awt.Button;
        import java.awt.BorderLayout;
        import java.awt.Panel;
        import javax.swing.JFrame;
        import javax.swing.JLabel;
        import javax.swing.JPanel;

        /**
         * Instructions:
         *
         * The following snippet demonstrates a severe performance regression in AWT
         * starting in 1.4 (merlin), and still present in the current version of the JDK
         * (tiger beta 2). In a multimonitor Windows XP environment set up as a single
         * display area (my video setup is two NEC MultiSync LCD 1980SX monitors using
         * an NVIDIA Quadro NVS graphics card), take the window and drag it rapidly
         * between the two monitors. In the AWT program, the event dispatch thread is
         * frozen while all of the surface datas are being recreated in the hierarchy
         * (in Win32SurfaceData.initOps). Note that the Swing program does not exhibit
         * the behavior because it does not have native peers.
         */
        public class Test {

            private static final int NESTED_PANELS = 25;

            // This one is very slow!
            public static void testAWT() {
                Frame frame = new Frame("AWT Test");
                frame.addWindowListener(new WindowAdapter() {
                    public void windowClosing(WindowEvent ev) {
                        System.exit(0);
                    }
                });
                frame.setLayout(new BorderLayout());
                Label label = new Label("Hello world");
                frame.add(label, BorderLayout.NORTH);
                Panel panel = new Panel(new BorderLayout());
                Panel currentPanel = panel;
                for (int i = 0; i < NESTED_PANELS; i++) {
                    Panel newPanel = new Panel(new BorderLayout());
                    currentPanel.add(newPanel, BorderLayout.CENTER);
                    currentPanel = newPanel;
                }
                currentPanel.add(new Label("Test"));
                frame.add(panel, BorderLayout.CENTER);
                Button btn = new Button("OK");
                frame.add(btn, BorderLayout.SOUTH);
                frame.pack();
                frame.setVisible(true);
            }

            // This one works swell!
            public static void testSwing() {
                JFrame frame = new JFrame("Swing Test");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.getContentPane().setLayout(new BorderLayout());
                JLabel label = new JLabel("Hello world");
                frame.getContentPane().add(label, BorderLayout.NORTH);
                JPanel panel = new JPanel(new BorderLayout());
                JPanel currentPanel = panel;
                for (int i = 0; i < NESTED_PANELS; i++) {
                    JPanel newPanel = new JPanel(new BorderLayout());
                    currentPanel.add(newPanel, BorderLayout.CENTER);
                    currentPanel = newPanel;
                }
                currentPanel.add(new Label("Test"));
                frame.getContentPane().add(panel, BorderLayout.CENTER);
                Button btn = new Button("OK");
                frame.getContentPane().add(btn, BorderLayout.SOUTH);
                frame.pack();
                frame.setVisible(true);
            }

            public static void main(String[] args) {
                testAWT();
                // testSwing();
            }
        }

        ---------- END SOURCE ----------

        CUSTOMER SUBMITTED WORKAROUND :
        The fix (WPanelPeer.java) :

        private void recursiveDisplayChanged(Component component)
            {
                if(component instanceof Container)
                {
                    Component acomponent[] = ((Container)component).getComponents();
                    for(int i = 0; i < acomponent.length; i++)
                        recursiveDisplayChanged(acomponent[i]);
                 }
                 
                java.awt.peer.ComponentPeer componentpeer = component.getPeer();
                //sanjiv: added this if condition so that WPanelPeer displayChanged() is not called //which will again call this method
               System.out.println("Component : " + component.getName());
                if(componentpeer != null && (componentpeer instanceof WPanelPeer)){
                 super.displayChanged();
                }
                else
                if(componentpeer != null && (componentpeer instanceof WComponentPeer))
                {
                    WComponentPeer wcomponentpeer = (WComponentPeer)componentpeer;
                    wcomponentpeer.displayChanged();
                }
            }
        (Incident Review ID: 296521)
        ======================================================================

              bchristi Brent Christian
              rmandalasunw Ranjith Mandala (Inactive)
              Votes:
              0 Vote for this issue
              Watchers:
              0 Start watching this issue

                Created:
                Updated:
                Resolved:
                Imported:
                Indexed: