JDK-8017146 : Memory Leak while drawing an AttributedString
  • Type: Bug
  • Component: client-libs
  • Sub-Component: 2d
  • Affected Version: 7u21
  • Priority: P3
  • Status: Closed
  • Resolution: Fixed
  • OS: windows_7
  • Submitted: 2013-06-11
  • Updated: 2013-11-13
  • Resolved: 2013-10-07
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 8
8Fixed
Related Reports
Duplicate :  
Description
FULL PRODUCT VERSION :
java version  " 1.7.0_21 " 
Java(TM) SE Runtime Environment (build 1.7.0_21-b11)
Java HotSpot(TM) Client VM (build 23.21-b01, mixed mode, sharing)

ADDITIONAL OS VERSION INFORMATION :
Microsoft Windows [Version 6.1.7601]

A DESCRIPTION OF THE PROBLEM :
Memory cumulates in process explorer, while the heap stays constant. This results in a  " java.lang.OutOfMemoryError: unable to create new native thread " .

STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Use the code provided to test the memory leak. If you comment the lines 9-10 out and uncomment line 12 everything goes right.

EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
The memory should not leak.
ACTUAL -
It is leaking.

ERROR MESSAGES/STACK TRACES THAT OCCUR :
java.lang.OutOfMemoryError: unable to create new native thread

REPRODUCIBILITY :
This bug can be reproduced always.

---------- BEGIN SOURCE ----------
final JFrame frm = new JFrame();
frm.getContentPane().setLayout(new BorderLayout());
frm.getContentPane().add(new JLabel() {
@Override public void paint(Graphics g)
{
super.paint(g);
Graphics2D gd = (Graphics2D) g;
// Memory leaking:
AttributedString as = new AttributedString( " this is a memory leak " , gd.getFont().getAttributes());
gd.drawString(as.getIterator(), 100, 100);
// No memory leak:
// gd.drawString( " no memory leak here " , 100, 100);
}
}, BorderLayout.CENTER);
frm.setSize(500,350);
frm.setLocationRelativeTo(null);
frm.setVisible(true);
new Thread() {
@Override public void run() {
while(true)
{
try
{
frm.getContentPane().repaint();
Thread.sleep(1);
} catch (InterruptedException ex)
{
Logger.getLogger(SIMAVIS_S_Main.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
}.start();
---------- END SOURCE ----------

CUSTOMER SUBMITTED WORKAROUND :
Like described above, if you use gd.drawString( " mystring " , ...) instead of AttributedString as the first argument the memory wouldn't leak.
Comments
With a complete test case (which I had to write) I was quickly able to confirm this is a duplicate of a bug 8015334 already fixed in 7u40 and JDK 8.
07-10-2013

11 hours in a tight loop before running out of memory? Sounds like we should be looking for a small fixed size data structure that's allocated somewhere inside each call to the native ICU layout engine but not freed before return.
04-10-2013

The test program crashed with OutOfMemoryError after running for 711m21.408s. But the heap sizes seem to be consistent after each GC execution (see gc.log.gz). I don't think there's any memory leak problems with AttibutedString. I suspent from hs_err_pid220.log that there might be some problems with the native text rendering code. I'm transferring this one to 2D for further evaluation.
03-10-2013