Note that there are some explanatory texts on larger screens.

plurals
  1. POHow to resolve OutOfMemoryError with ImageIO plugins as the cause?
    primarykey
    data
    text
    <p>At work we have some tomcat servers running several webapps, about half of which have to do some image processing. </p> <p>Before doing their image processing, these webapps do a <code>ImageIO.scanForPlugins()</code> to get the appropriate image readers and writers into memory. While before this was just run anytime an image needed to be processed, we now run the scan only when the webapps are initialized (since we don't add any jars after running, why run the scan more than once?)</p> <p>Some days later, the tomcat instance crashed due to an <code>OutOfMemoryError</code>. Luckily we had the <code>HeapDumpOnOutOfMemoryError</code> option set, so I looked at the heap dump. In the dump I found that 97% of memory was taken by an instance of a <code>javax.imageio.spi.PartialOrderIterator</code>. Most of that space was taken up by it's backing <code>java.util.LinkedList</code>, which had 18 million elements. The linked list is made up of <code>javax.imageio.spi.DigraphNode</code>, which contains the image readers and writers loaded by <code>ImageIO.scanForPlugins()</code>.</p> <p>"Aha", I thought, "we must be running the scan in a loop somewhere and we're just adding the same elements over and over again". But, I figured I should double check this assumption, so I wrote the following test class:</p> <pre><code>import javax.imageio.ImageIO; public class ImageIOTesting { public static void main(String[] args) { for (int i = 0; i &lt; 100000; i++) { ImageIO.scanForPlugins(); if (i % 1000 == 0) { System.out.println(Runtime.getRuntime().totalMemory() / 1024); } } } } </code></pre> <p>However, when I run this class on the server environment, the amount of memory in use never changes! </p> <p>A quick dig through the source of the javax.imageio packages shows that the scan checks to see if a service provider is already registered, and if so it deregisters the old provider before registering the new one. So now the question is: Why do I have this giant linked list of service providers? Why are they stored as a directed graph? And more importantly, how do I prevent this from happening?</p>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload