JDK-8040617 : [macosx] Large JTable cell results in a OutOfMemoryException
  • Type: Bug
  • Component: client-libs
  • Sub-Component: 2d
  • Affected Version: 7u40,8,9
  • Priority: P3
  • Status: Resolved
  • Resolution: Fixed
  • OS: os_x
  • Submitted: 2013-09-16
  • Updated: 2015-06-04
  • Resolved: 2014-08-26
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
JDK 7 JDK 8 JDK 9
7u67Fixed 8u31Fixed 9 b32Fixed
Related Reports
Duplicate :  
Duplicate :  
Description
FULL PRODUCT VERSION :
Java(TM) SE Runtime Environment (build 1.7.0_40-b43)
Java HotSpot(TM) 64-Bit Server VM (build 24.0-b56, mixed mode)


ADDITIONAL OS VERSION INFORMATION :
Mac OS X 10.8.5 (Mountain Lion)

A DESCRIPTION OF THE PROBLEM :
This very same bug was reported as http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=7181956 in December 2012. It disappeared from the bug database during the spring 2013...

This test class demonstrates an OutOfMemoryError that occurs on Mac OS X 10.8.5 running Java 1.7.0_40 (using default JVM parms) and the Mac OS X look and feel. The problem happen when having a very large string in single column JTable. It occurs at a certain level when increasing the value of TableColumn.setPreferredWidth(). Just before the OutOfMemoryError happen some garbage graphics is painted in the table header. For me the garbage in the table header is rendered when setting preferred width to a value around 5000 (scroll horizontally and the garbage will appear). The OutOfMemoryError occur at a value of approx 10000 and when clicking in the table. This is the full error:

Exception in thread "AWT-EventQueue-0" java.lang.OutOfMemoryError: can't create offscreen surface
   at sun.java2d.opengl.OGLSurfaceData.initSurfaceNow(OGLSurfaceData.java:298)
   at sun.java2d.opengl.OGLSurfaceData.access$000(OGLSurfaceData.java:98)
   at sun.java2d.opengl.OGLSurfaceData$1.run(OGLSurfaceData.java:324)
   at sun.java2d.opengl.OGLRenderQueue$QueueFlusher.run(OGLRenderQueue.java:234)

Running the same test program with Java 1.6.0_51 works fine with a preferred width set to several millions.

Note the problem occur only with the Mac OS X L&F. I've tried Metal and Alloy and these work fine.


REGRESSION.  Last worked in version 6u45

STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Run the test case and set the width for the column to 5000 (and press enter). Now scroll horizontally and you will notice garbage graphics in the column header.

Increase the width to 10000 and now scroll horizontally, the OOME exception is thrown

EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
JTableHeader should renderer the column header just fine and there should be no OOME
ACTUAL -
If running setPreferredWidth() to a high value an OOME is reported.

Also, the JTableHeader is rendering garbage in the header for the failing column

ERROR MESSAGES/STACK TRACES THAT OCCUR :
Exception in thread "AWT-EventQueue-0" java.lang.OutOfMemoryError: can't create offscreen surface
   at sun.java2d.opengl.OGLSurfaceData.initSurfaceNow(OGLSurfaceData.java:298)
   at sun.java2d.opengl.OGLSurfaceData.access$000(OGLSurfaceData.java:98)
   at sun.java2d.opengl.OGLSurfaceData$1.run(OGLSurfaceData.java:324)
   at sun.java2d.opengl.OGLRenderQueue$QueueFlusher.run(OGLRenderQueue.java:234)


REPRODUCIBILITY :
This bug can be reproduced always.

---------- BEGIN SOURCE ----------
import java.awt.BorderLayout;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.*;
import javax.swing.table.AbstractTableModel;

public class BigStringErrorOnOSX extends JFrame {

   public static void main(String[] args) {
      SwingUtilities.invokeLater(new Runnable() {
         @Override
         public void run() {
            BigStringErrorOnOSX t = new BigStringErrorOnOSX();
            t.setSize(1000, 200);
            t.setVisible(true);
         }
      });
   }

   public BigStringErrorOnOSX() {
      final JTable table = new JTable(new DummyModel());
      table.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);

      final JTextField widthField = new JTextField(10);
      widthField.addActionListener(new ActionListener() {
         @Override
         public void actionPerformed(ActionEvent e) {
            table.getColumnModel().getColumn(0).setPreferredWidth(Integer.parseInt(widthField.getText()));
         }
      });
      JPanel topPanel = new JPanel(new FlowLayout());
      topPanel.add(new JLabel("setPreferredWidth for column 0:"));
      topPanel.add(widthField);

      add(topPanel, BorderLayout.NORTH);
      add(new JScrollPane(table), BorderLayout.CENTER);
   }

   class DummyModel extends AbstractTableModel {
      private String bigString;

      DummyModel() {
         StringBuilder b = new StringBuilder();
         int n = 0;
         for (int i = 0; i < 100000; i++) {
            b.append(n++);
            if (n > 9) {
               n = 0;
            }
         }
         bigString = b.toString();
      }

      @Override
      public int getRowCount() {
         return 1;
      }

      @Override
      public int getColumnCount() {
         return 1;
      }

      @Override
      public Object getValueAt(int rowIndex, int columnIndex) {
         return bigString;
      }
   }
}

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

CUSTOMER SUBMITTED WORKAROUND :
Do not use the AquaLookAndFeel
Comments
SQE OK to take the fix into CPU15_01
29-08-2014

Justification: regression - and, also a BPR fix - see dup.
28-08-2014

The problem happens when we are trying to create an accelerated copy for a buffered image with dimension exceeded GL_MAX_TEXTURE_SIZE. An artificial OOME is thrown as an indicator of surface initialization failure. Suggested fix handles the exception in createManagedSurface() in the same manner as it is handled in CGLVolatileSurfaceManager: we return 'null' instead of accelerated surface data, that result of using original surface data instead of accelerated. Fix review: http://mail.openjdk.java.net/pipermail/2d-dev/2014-August/004765.html
22-08-2014

Per agreement with Victor sustaining takes all the bugs that formally reported against JDK7. We may return them back after the evaluation if some of them are reproducible on JDK8 or 9.
07-05-2014

Will need review for >= JDK 7 Moving to 7u80 and will review ASAP. Ping me directly with any concerns about this move.
22-04-2014

is it affecting 8 or 9?
16-04-2014