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 ima开发者_JS百科ge 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
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 aSoftCache
entry is no longer strongly reachable, then it may remove that entry in order to release the memory occupied by the value object. AllSoftCache
objects are guaranteed to be completely cleared before the virtual machine will throw anOutOfMemoryError
.
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.
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?
精彩评论