JDK-5079092 : REGRESSION:GridBagLayout causes an extreme slowdown during doLayout on Liunx
  • Type: Bug
  • Component: client-libs
  • Sub-Component: java.awt
  • Affected Version: 5.0
  • Priority: P3
  • Status: Closed
  • Resolution: Duplicate
  • OS: linux
  • CPU: x86
  • Submitted: 2004-07-27
  • Updated: 2004-07-29
  • Resolved: 2004-07-29
Related Reports
Duplicate :  
Description
###@###.### 2004-07-27

J2SE Version (please include all output from java -version flag):
 java version "1.5.0-beta3"
 Java(TM) 2 Runtime Environment, Standard Edition (build 1.5.0-beta3-b59)
 Java HotSpot(TM) Client VM (build 1.5.0-beta3-b59, mixed mode)

Does this problem occur on J2SE 1.3, 1.4 or 1.4.1?  Yes / No (pick one)
 Works fine with windows machine or on Linux under JDK1.3.
 But slowness happen on Linux JDK1.4.2 and the latest JDK1.5 beta.

Operating System Configuration Information (be specific):
 Linux

Bug Description:
  Found a problem with GridBagLayout which causes an extreme
  slowdown (up to a minute) during the doLayout method. It occurs on
  Linux, JDK1.4.2 and the latest JDK1.5 beta. It does not occur on Windows
  or on Linux under JDK1.3 and the performance of layout is almost
  instantaneous. 
 
  We have a window, which is a JComponent, which includes a canvas which
  is also a JComponent and two JScrollbars. We initialize the window like
  this:
 
  GridBagConstraints constraints = new GridBagConstraints();
 
  constraints.gridx = 0;
  constraints.gridy = 0;  
  constraints.weightx = 1;
  constraints.weighty = 1;
  constraints.fill = GridBagConstraints.BOTH;
 
  this.add(canvas, constraints);
 
  this.horizontalScrollBar = new JScrollBar(SwingConstants.HORIZONTAL);
 
  this.verticalScrollBar = new JScrollBar(SwingConstants.VERTICAL);
 
  GridBagConstraints constraints = new GridBagConstraints();
 
   constraints.gridx = 1;
   constraints.gridy = 0;
   
 
   constraints.weightx = 0;
   constraints.weighty = 0;
   constraints.fill = GridBagConstraints.VERTICAL;
 
   this.add(this.verticalScrollBar, constraints);
 
   constraints.gridx = 0;
   constraints.gridy = 1;
   
    constraints.weightx = 0;
   constraints.weighty = 0;
   constraints.fill = GridBagConstraints.HORIZONTAL;
 
   this.add(this.horizontalScrollBar, constraints);
 
 
  At this point everything shows up ok.
 
  Then, when a certain action happens, we need to hide the scrollbars.  We
  do it like this:
 
    horizontalScrollBar.setVisible(false);
    verticalScrollBar.setVisible(false);
   
    this.doLayout();
    
     SwingUtilities.invokeLater(
      new Runnable()
      {
       public void run()
       {
        getHorizontalScrollBar().revalidate();
        getVerticalScrollBar().revalidate();
       }
      });
   }
 
  This is when the slowdown occurs and it takes up to a minute for
  scrollbars to disappear. It's almost instantaneous on JDK1.3 and on
  Windows platform, but very slow on Linux JDK1.4.2_04 and 1.5 beta build 58
 
  There is additional factor which may or may not be relevant.  When
  the canvas is resized (as happens during the doLayout call) we need to
  repaint the drawing that is painted on it.  So we override the setBounds
  method like this:
 
  public void setBounds(int x, int y, int width, int height)
   {
    super.setBounds(x, y, width, height);
    Image buffer = this.createImage(width, height);
    draw(buffer.getGraphics());

   }
 
  The draw routine is pretty complicated, but our customer who initially
  found the problem gave us a snapshot stack of the thread when the
  slowdown occurs.  Here is the relevant portion:
 
  at sun.awt.image.DataBufferNative.setElem(Native Method)
  at sun.awt.image.DataBufferNative.setElem(DataBufferNative.java:71)
  at java.awt.image.DataBuffer.setElem(DataBuffer.java:244)
  at
java.awt.image.SinglePixelPackedSampleModel.setDataElements(SinglePixelPackedSampleModel.java:605)
  at java.awt.image.WritableRaster.setDataElements(WritableRaster.java:265)
  at sun.java2d.loops.SolidPixelWriter.writePixel(GeneralRenderer.java:863)
  at sun.java2d.loops.GeneralRenderer.doSetRect(GeneralRenderer.java:141)
  at sun.java2d.loops.SetFillRectANY.FillRect(GeneralRenderer.java:615)
  at sun.java2d.pipe.LoopPipe.fillRect(LoopPipe.java:106)
  at sun.java2d.pipe.ValidatePipe.fillRect(ValidatePipe.java:46)
  at sun.java2d.SunGraphics2D.fillRect(SunGraphics2D.java:2066)
 

Steps to Reproduce (be specific):
 - Add attached tsall.jar to the classpath
 - Compile SimpleEditor.java
 - run SimpleEditor 

You will see a window with a grey rectangle. Drag the grey rectangle to the
edge of the window.

Result: scrollbars will appear. On Windows and Linux JDK1.3.1 this is
instantaneious, but on Linux JDK1.4+ it will take some time.


Comments
EVALUATION I'd like to suggest AWT have a look at this first since it is on a specific platform and GridBagLayout belongs to them. ###@###.### 2004-07-27 I would be nice to investigate this problem, but to do this quickly we need either small standalone test or sources of tsall.jar. Because attached tests just creates instance of one of custom components and shows it. So, the problem is somewhere inside. Also I'm not sure if this is a GridBahLayout's problem because the test spends most of his time in painting routines. ###@###.### 2004-07-28 We need source codes of all objects involved into the problem ###@###.### 2004-07-29 Without the source code, the stacks looks like this: "AWT-EventQueue-0" prio=1 tid=0x08467c98 nid=0x1e38 runnable [0x4ba86000..0x4ba87480] at sun.awt.image.DataBufferNative.setElem(Native Method) at sun.awt.image.DataBufferNative.setElem(DataBufferNative.java:71) at java.awt.image.DataBuffer.setElem(DataBuffer.java:244) at java.awt.image.SinglePixelPackedSampleModel.setDataElements(SinglePixelPackedSampleModel.java:611) at java.awt.image.WritableRaster.setDataElements(WritableRaster.java:268) at sun.java2d.loops.SolidPixelWriter.writePixel(GeneralRenderer.java:863) at sun.java2d.loops.GeneralRenderer.doSetRect(GeneralRenderer.java:141) at sun.java2d.loops.SetFillRectANY.FillRect(GeneralRenderer.java:615) at sun.java2d.pipe.LoopPipe.fillRect(LoopPipe.java:104) at sun.java2d.pipe.ValidatePipe.fillRect(ValidatePipe.java:58) at sun.java2d.SunGraphics2D.fillRect(SunGraphics2D.java:2150) at com.tomsawyer.editor.graphics.TSEDefaultGraphics.fillRect(DashoA9*..) at com.tomsawyer.editor.ui.TSEGraphUI.drawBackground(DashoA9*..) at com.tomsawyer.editor.TSEGraphWindow.drawGraph(DashoA9*..) at com.tomsawyer.editor.TSEGraphWindow.drawGraph(DashoA9*..) at com.tomsawyer.editor.TSEGraphWindow.drawGraph(DashoA9*..) at com.tomsawyer.editor.TSEGraphWindow.drawGraph(DashoA9*..) at com.tomsawyer.editor.TSEGraphWindow.drawGraph(DashoA9*..) at com.tomsawyer.editor.TSEGraphWindow.drawGraph(DashoA9*..) at com.tomsawyer.editor.TSEInnerCanvas.adjustBuffers(DashoA9*..) at com.tomsawyer.editor.TSEInnerCanvas.setBounds(DashoA9*..) at java.awt.GridBagLayout.ArrangeGrid(GridBagLayout.java:1565) at java.awt.GridBagLayout.arrangeGrid(GridBagLayout.java:1372) at java.awt.GridBagLayout.layoutContainer(GridBagLayout.java:712) at java.awt.Container.layout(Container.java:1401) at java.awt.Container.doLayout(Container.java:1390) at java.awt.Container.validateTree(Container.java:1473) at java.awt.Container.validateTree(Container.java:1480) at java.awt.Container.validateTree(Container.java:1480) at java.awt.Container.validateTree(Container.java:1480) at java.awt.Container.validateTree(Container.java:1480) at java.awt.Container.validate(Container.java:1448) - locked <0x433b9c78> (a java.awt.Component$AWTTreeLock) at java.awt.Window.dispatchEventImpl(Window.java:1764) at java.awt.Component.dispatchEvent(Component.java:3803) at java.awt.EventQueue.dispatchEvent(EventQueue.java:463) at java.awt.EventDispatchThread.pumpOneEventForHierarchy(EventDispatchThread.java:234) at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:163) at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:157) at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:149) at java.awt.EventDispatchThread.run(EventDispatchThread.java:110) Which shows that on every setBounds user component does painting through software renderer(BufferedImage) which is very slow. Here is the performance analysis: Flat profile of 29.63 secs (2576 total ticks): AWT-EventQueue-0 Interpreted + native Method 4.6% 0 + 59 sun.java2d.loops.MaskBlit.MaskBlit 0.7% 0 + 9 sun.awt.image.DataBufferNative.getElem 0.3% 0 + 4 sun.awt.X11PMBlitLoops.Blit 0.2% 3 + 0 javax.swing.JComponent.paintChildren 0.2% 0 + 2 sun.awt.X11.XInputMethod.setXICFocusNative 0.2% 0 + 2 sun.awt.X11.XlibWrapper.XTranslateCoordinates 0.2% 2 + 0 sun.awt.X11Renderer.fillRect 0.2% 2 + 0 sun.java2d.loops.OpaqueCopyAnyToArgb.Blit 0.1% 0 + 1 java.lang.Object.clone 0.1% 0 + 1 sun.awt.image.SurfaceManager.getSurfaceManager 0.1% 0 + 1 sun.misc.Unsafe.monitorExit 0.1% 0 + 1 sun.awt.X11.XlibWrapper.InternAtom 0.1% 0 + 1 sun.awt.image.DataBufferNative.setElem 0.1% 1 + 0 java.lang.ClassLoader.defineClass1 0.1% 0 + 1 sun.awt.image.BufImgSurfaceData.initRaster 0.1% 1 + 0 com.tomsawyer.editor.TSEGraphWindow.isDrawInvisibleOnDragging 0.1% 1 + 0 com.tomsawyer.drawing.geometry.TSConstRect.getCenterX 0.1% 1 + 0 sun.java2d.loops.SolidPixelWriter.writePixel 0.1% 1 + 0 com.tomsawyer.editor.ui.TSERectangularUI.drawEnabledGrapple 0.1% 1 + 0 java.util.HashSet.add 0.1% 1 + 0 com.tomsawyer.editor.TSEWindowInputTool.dragGestureRecognizedEvent 0.1% 1 + 0 com.tomsawyer.drawing.geometry.TSConstRect.withinYRange 0.1% 0 + 1 com.tomsawyer.editor.tool.TSESelectTool.moveSelected 0.1% 0 + 1 com.tomsawyer.editor.tool.TSEMoveSelectedTool.newMoveCommand 0.1% 1 + 0 java.awt.image.DataBuffer.<init> 8.6% 26 + 85 Total interpreted (including elided) Compiled + native Method 3.9% 50 + 0 java.awt.image.DirectColorModel.getRGB 2.7% 35 + 0 java.awt.image.DirectColorModel.getBlue 2.2% 29 + 0 java.awt.image.DirectColorModel.getRed 2.1% 27 + 0 java.awt.image.DirectColorModel.getGreen 1.0% 13 + 0 sun.java2d.loops.OpaqueCopyAnyToArgb.Blit 0.9% 11 + 0 java.awt.image.Raster.getDataElements 0.6% 8 + 0 sun.awt.image.DataBufferNative.getElem 0.2% 3 + 0 java.awt.image.DirectColorModel.getRGB 0.2% 3 + 0 java.awt.image.SinglePixelPackedSampleModel.getDataElements 0.2% 2 + 0 java.awt.image.DataBuffer.getElem 0.1% 1 + 0 java.awt.image.DataBuffer.setElem 0.1% 1 + 0 sun.awt.image.DataBufferNative.setElem 0.1% 1 + 0 java.awt.EventQueue.postEvent 14.2% 184 + 0 Total compiled Stub + native Method 65.1% 0 + 842 sun.awt.image.DataBufferNative.getElem 10.2% 0 + 132 sun.awt.image.DataBufferNative.setElem 75.3% 0 + 974 Total stub So, this is a bug in a user code - do not repaint on setBounds, use ComponentEvent for that instead. ###@###.### 2004-07-29 Although the test itself is not perfect, the problem may also be related to 4835595 (PixelGrabber.grabPixels runs up to 600 times slower on JDK1.4.1 than on JDK1.3.1) in this case setting sun.java2d.pmoffscreen property to false (-Dsun.java2d.pmoffscreen=false) may help. ###@###.### 2004-07-29
29-07-2004