5

这个问题是我上一个问题提供给我的答案的结果。

我被要求使用 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

苏米特

4

2 回答 2

3

图像缓存似乎是由一个名为SoftCache的类实现的,其文档说明如下:

接口的内存敏感实现Map

一个SoftCache对象使用java.lang.ref.SoftReference 来实现一个内存敏感的哈希映射。如果垃圾收集器在某个时间点确定 SoftCache条目中的值对象不再是强可达的,那么它可能会删除该条目以释放该值对象占用的内存。在SoftCache虚拟机抛出 OutOfMemoryError.

所以我不会担心这个缓存占用的内存,因为当其他地方需要内存时它会自动清除。

编辑:阅读SyntaxT3rr0rflush的评论后,我认为调用Image仍然值得。如果这是 larget 方法的一部分,您还可以将 image 设置为 null 或重构,以便它更快地超出范围。

另一种可能性是尝试 ImageIO Api 来检索宽度和高度。这应该可以通过获取图像类型的 ImageReader 来实现

于 2011-03-09T13:55:37.653 回答
1

您的 Image 对象是否有可能长时间保留在范围内?例如,如果它包含在一段长时间运行的代码块的外部范围内,它可能不会被正确地进行垃圾收集。

有时(在极少数情况下),将 Image 对象引用显式设置为 null 是有益的。这在我上面提到的情况下是正确的。有关详细信息,请参阅以下问题:在 Java 中将对象分配给 null 会影响垃圾收集吗?

于 2011-03-09T13:27:22.827 回答