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

ICC_Profile has un-needed, not-empty finalize method

    XMLWordPrintable

Details

    • 2d
    • b25
    • generic
    • windows_7

    Backports

      Description

        FULL PRODUCT VERSION :
        java version "9-ea"
        Java(TM) SE Runtime Environment (build 9-ea+157)
        Java HotSpot(TM) 64-Bit Server VM (build 9-ea+157, mixed mode)

        ADDITIONAL OS VERSION INFORMATION :
        Microsoft Windows [Version 6.1.7601]

        A DESCRIPTION OF THE PROBLEM :
        The code is not only very slow, it has a huge memory footprint that has no relation to the -Xmx setting.

        While the code may look silly, it is reduced from a production case where it is done like this because
        - we need to initialize the colorspace due to avoid concurrency problems in java (see JDK-8058973) and to catch other ICC exceptions early (e.g. https://issues.apache.org/jira/browse/PDFBOX-3610 , https://issues.apache.org/jira/browse/PDFBOX-3549 , https://issues.apache.org/jira/browse/PDFBOX-3531 )
        - we had a case with 5000 images with separate ICC profile. This took very long and used up to 5 GB

        The problem happens also in JDK8 121.

        STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
        Run
        java -Xmx200m -jar PDFBOX3641IccTest.jar

        and start the windows task manager and enable the column that shows the used memory. The used memory goes well over 2GB. This code runs for about 7min, and ends with

        7 min 15 sec
        used memory: 47 MB, max: 209 MB


        (I also tried to add the option -XX:MaxMetaspaceSize=200m but this didn't help either)

        The values "used memory: 47 MB, max: 209 MB" are similar to what I see in Netbeans profiler telemetry. There used memory never goes very high, but the windows memory usage does.


        EXPECTED VERSUS ACTUAL BEHAVIOR :
        EXPECTED -
        I'd expect that the used memory is well below 1GB.
        ACTUAL -
        Used memory well over 2GB.

        REPRODUCIBILITY :
        This bug can be reproduced always.

        ---------- BEGIN SOURCE ----------
        import java.awt.Color;
        import java.awt.color.ICC_ColorSpace;
        import java.awt.color.ICC_Profile;
        import java.io.ByteArrayOutputStream;
        import java.io.IOException;
        import java.io.InputStream;
        import java.net.URL;

        public class PDFBOX3641IccTest
        {
            public static void main(String[] args) throws IOException
            {
                ByteArrayOutputStream baos = new ByteArrayOutputStream();
                try (InputStream is = new URL("https://issues.apache.org/jira/secure/attachment/12854386/PDFBOX-3641.icc").openStream())
                {
                    int by;
                    while ((by = is.read()) != -1)
                    {
                        baos.write(by);
                    }
                }
                byte[] ba = baos.toByteArray();
                
                long t0 = System.currentTimeMillis();
                for (int i = 0; i < 5000; ++i)
                {
                    ICC_Profile profile = ICC_Profile.getInstance(ba);
                    ICC_ColorSpace cs = new ICC_ColorSpace(profile);
                    cs.toRGB(new float[cs.getNumComponents()]);
                    cs.fromRGB(new float[3]);
                    cs.toCIEXYZ(new float[cs.getNumComponents()]);
                    cs.fromCIEXYZ(new float[3]);
                    new Color(cs, new float[cs.getNumComponents()], 1f);
                    
        // if ((i % 500) == 0)
        // Runtime.getRuntime().gc();
                }
                
                long duration = (System.currentTimeMillis() - t0) / 1000;
                System.out.println(String.format("%d min %d sec", duration / 60, duration % 60));
                System.out.println("used memory: " + (Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory()) / 1000000 + " MB, max: " +

        Runtime.getRuntime().maxMemory() / 1000000 + " MB");
            }
        }

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

        CUSTOMER SUBMITTED WORKAROUND :
        Surprisingly, the total used windows memory is much less if the commented-out code is activated, which does a gc() call every 500 iterations. This is kindof weird as I'd expect that gc is "smart" enough to act when memory gets low.

        Or could it be that the memory used by ICC is not measured, so that gc doesn't notice by itself that a lot is used?

        Attachments

          Issue Links

            Activity

              People

                prr Philip Race
                webbuggrp Webbug Group
                Votes:
                1 Vote for this issue
                Watchers:
                9 Start watching this issue

                Dates

                  Created:
                  Updated:
                  Resolved: