图像被缓存并耗尽了我的堆空间
这个问题是针对我的上一个问题。
我被要求使用 Eclipse MAT 来调查是什么占用了我的堆。以下是我的观察结果(主要消费者):
class sun.awt.SunToolkit 333.7 MB
com.tennisearth.service.impl.CacheManagerServiceImpl 136 MB
org.apache.jasper.servlet.JspServlet 91.5 MB
我已经使用 CacheManageServiceImpl
解决了该问题,但需要 SunToolkit
的帮助。
下面是创建 Image 对象的代码(内部使用 SunToolkit.imgCache
),
Image img = new ImageIcon(imagePath).getImage();
int imageWidth = img.getWidth(null);
int imageHeight = img.getHeight(null);
请注意,创建 Image 对象只是为了获取稍后在某些逻辑中需要的图像的宽度/高度。
有没有办法禁用 SunToolkit
图像缓存?更好的是,有没有办法清除这个缓存?或者有更好的方法可以检索这些信息吗?
顺便说一句,供您参考,我使用以下命令来运行 jboss(请注意堆大小参数):
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
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
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
图像缓存似乎是由名为 SoftCache,其文档说明如下:
所以我不会担心这个缓存占用的内存,因为当其他地方需要内存时它会自动清除。
编辑:阅读SyntaxT3rr0r的评论后,我认为它仍然可能是值得对图像调用
flush
。如果这是大型方法的一部分,您还可以将 image 设置为 null 或重构,以便它更快地超出范围。另一种可能性是尝试使用 ImageIO Api 来检索宽度和高度。这应该可以通过获取 图像类型的ImageReader。
The image cache seems to be implemented by a class named SoftCache, its documentation states the following:
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.
您的 Image 对象是否可能长时间保留在范围内?例如,如果它包含在长时间运行的代码块的外部范围中,则可能无法正确进行垃圾收集。
有时(在极少数情况下),将 Image 对象引用显式设置为 null 是有益的。我上面提到的情况就是如此。有关详细信息,请参阅以下问题: 是否将对象分配给Java中的null影响垃圾回收吗?
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?