Java Solaris Communities Sun Store Join SDN My Profile Why Join?
 
Bug Database
Bug Detail
Quick Lists
Top 25 Bugs
Top 25 RFE's
Recently Closed Bugs
Printable Page Printable Page


Bug Database
Bug ID: 6728838
Votes 0
Synopsis Native memory leak in StrikeCache.java
Category java:classes_2d
Reported Against
Release Fixed 7(b54)
State 10-Fix Delivered, bug
Priority: 3-Medium
Related Bugs
Submit Date 23-JUL-2008
Description
FULL PRODUCT VERSION :
Java(TM) SE Runtime Environment (build1.6.0-internal-fastdebug-tonyd_21_jul_2008_15_00-b00)

ADDITIONAL OS VERSION INFORMATION :
Os independent (will happen on any OS).

A DESCRIPTION OF THE PROBLEM :
There is a memory leak in j2se/src/share/classes/sun/font/StrikeCache.java which can occur when disposeStrike is called for a FontStrikeDisposer that has no glyph images. In this case, the memory allocated for the pScalerContext is never freed.

The fix is to add a final else if clause to free the scaler context at line 217.

e.g.:

static void disposeStrike(FontStrikeDisposer disposer) {
        if (disposer.intGlyphImages != null) {
            freeIntMemory(disposer.intGlyphImages,
                          disposer.pScalerContext);
        } else if (disposer.longGlyphImages != null) {
            freeLongMemory(disposer.longGlyphImages,
                           disposer.pScalerContext);
        } else if (disposer.segIntGlyphImages != null) {
            /* NB Now making multiple JNI calls in this case.
             * But assuming that there's a reasonable amount of locality
             * rather than sparse references then it should be OK.
             */
            for (int i=0; i<disposer.segIntGlyphImages.length; i++) {
                if (disposer.segIntGlyphImages[i] != null) {
                    freeIntMemory(disposer.segIntGlyphImages[i],
                                  disposer.pScalerContext);
                    /* native will only free the scaler context once */
                    disposer.pScalerContext = 0L;
                    disposer.segIntGlyphImages[i] = null;
                }
            }
            /* This may appear inefficient but it should only be invoked
             * for a strike that never was asked to rasterise a glyph.
             */
            if (disposer.pScalerContext != 0L) {
                freeIntMemory(new int[0], disposer.pScalerContext);
            }
        } else if (disposer.segLongGlyphImages != null) {
            for (int i=0; i<disposer.segLongGlyphImages.length; i++) {
                if (disposer.segLongGlyphImages[i] != null) {
                    freeLongMemory(disposer.segLongGlyphImages[i],
                                   disposer.pScalerContext);
                    disposer.pScalerContext = 0L;
                    disposer.segLongGlyphImages[i] = null;
                }
            }
            if (disposer.pScalerContext != 0L) {
                freeLongMemory(new long[0], disposer.pScalerContext);
            }
        }
// NEW ELSE IF CLAUSE HERE!
        else if (disposer.pScalerContext != 0L) {
            // tpd - If we never had glyph images, but we did allocate
            //       a scaler context, we must free the scaler context!
            freeIntMemory(new int[0], disposer.pScalerContext);
        }


It would be great if this fix could be integrated into an upcoming release!

Thanks,
  Tony



REPRODUCIBILITY :
This bug can be reproduced always.
Posted Date : 2008-07-23 10:56:50.0
Work Around
N/A
Evaluation
Suggested fix is partly correct. Needs distinguish the 32 bit and 64 bit cases :

        } else if (disposer.pScalerContext != 0L) {
            /* Rarely a strike may have been created that never cached
             * any glyphs. In this case we still want to free the scaler
             * context.
             */
            if (FontManager.longAddresses) {
                freeLongMemory(new long[0], disposer.pScalerContext); 
            } else {
                freeIntMemory(new int[0], disposer.pScalerContext);
            }
        }
Posted Date : 2008-07-23 17:51:05.0
Comments
  
  Include a link with my name & email   


PLEASE NOTE: JDK6 is formerly known as Project Mustang