Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Images getting cached and eating up my Heap Space

This question is a result of the answers provided to me for my previous question.

I was asked to use Eclipse MAT to investigate what is eating up my heap. Below are my observations (Top Consumers):

class sun.awt.SunToolkit                                 333.7 MB
com.tennisearth.service.impl.CacheManagerServiceImpl     136 MB
org.apache.jasper.servlet.JspServlet                     91.5 MB

I have already fixed the issue with CacheManageServiceImpl, but require help with SunToolkit.

Below is the code that creates an Image object (which internally uses SunToolkit.imgCache)

Image img = new ImageIcon(imagePath).getImage();
int imageWidth = img.getWidth(null);
int imageHeight = img.getHeight(null);

Plz note that the Image object is only being created to get the width / height of the image which is required later in some logic.

Is there a way to disable SunToolkit image caching? Better yet, is there a way to clear this cache? Or is there a better way I can retrieve this information?

BTW for your reference, I am using the below command to run jboss (plz note the heap size arguments):

java -Dprogram.name=run.sh -server -Xms256m -Xmx1024m -XX:PermSize=64m -XX:MaxPermSize=256m -verbose:gc -Xloggc:/data1/logs/jboss/GC.log -XX:+HeapDumpOnOutOfMemoryError -Dsun.rmi.dgc.client.gcInterval=3600000 -Dsun.rmi.dgc.server.gcInterval=3600000 -Dorg.apache.catalina.STRICT_SERVLET_COMPLIANCE=false -Djava.net.preferIPv4Stack=true -Djava.library.path=/usr/local/java/jboss-4.2.2.GA/bin/native -Djava.endorsed.dirs=/usr/local/java/jboss-4.2.2.GA/lib/endorsed -classpath /usr/local/java/jboss-4.2.2.GA/bin/run.jar:/usr/local/java/jdk1.6.0_06/lib/tools.jar org.jboss.Main -c default -b <IP_ADDRESS> -Djboss.messaging.ServerPeerID=1

Sumit

like image 319
Sumit Avatar asked Oct 11 '22 13:10

Sumit


2 Answers

The image cache seems to be implemented by a class named SoftCache, its documentation states the following:

A memory-sensitive implementation of the Map interface.

A SoftCache object uses java.lang.ref.SoftReference to implement a memory-sensitive hash map. If the garbage collector determines at a certain point in time that a value object in a SoftCache entry is no longer strongly reachable, then it may remove that entry in order to release the memory occupied by the value object. All SoftCache objects are guaranteed to be completely cleared before the virtual machine will throw an OutOfMemoryError.

So I would not worry about the memory taken by this cache since it will get cleared automatically when the memory is needed elsewhere.

Edit: After reading the comments by SyntaxT3rr0r, I think it could still be worthwhile to call flush on the Image. If this is part of a larget method you could also set image to null or refactor so it goes out of scope sooner.

Another possibility would be to try the ImageIO Api to retrieve the width and height. This should be possible by getting a ImageReader for the image type.

like image 115
Jörn Horstmann Avatar answered Oct 15 '22 10:10

Jörn Horstmann


Is it possible your Image object remains in scope for long periods of time? For example, if it's contained in the outer scope of a block of code that runs for long periods of time, it may not be properly garbage collected.

Sometimes (in rare cases), it's beneficial to explicitly set your Image object reference to null. This would be true in the case I mentioned above. See the following question for more info: Does assigning objects to null in Java impact garbage collection?

like image 27
Madison Caldwell Avatar answered Oct 15 '22 11:10

Madison Caldwell