我正在使用LWUIT编写MIDlet,图像似乎耗尽了大量的内存。我使用的所有图像都是PNG,并打包在JAR文件中。我使用标准的Image.createImage(URL)方法加载它们。应用程序有许多表单,每个表单都有一些标签和按钮,但我相当确定只有活动表单保存在内存中(我知道它不是很值得信赖,但Runtime.freeMemory()似乎确认这一点)。
该应用程序在240x320分辨率下运行良好,但将其移至480x640并使用适当大的UI图像开始导致出现内存不足错误。除其他外,应用程序的功能是下载远程图像。该应用程序似乎工作正常,直到它到达这一点。下载几个PNG并返回主菜单后,遇到内存不足错误。当然,我查看了主菜单使用的内存量,这非常令人震惊。这只是带有图像和四个按钮的两个标签。每个按钮都有三个用于style.setIcon,setPressedIcon和setRolloverIcon的图像。图像的大小范围为15到25KB,但删除了每个按钮使用的三个图像中的两个(总共8个图像),Runtime.freeMemory()显示内存使用量减少了1MB。
我看到它的方式,我要么有很多内存泄漏(我不认为我这样做,但内存泄漏并不是很容易被人追踪),我正在做一些非常错误的事情图像处理或者确实没有问题,我只需要缩小。
如果有人有任何提供的见解,我将不胜感激。
答案 0 :(得分:2)
移动设备的内存通常非常低。所以你必须使用一些技巧来保存和使用记忆。
我们在一个项目中遇到了同样的问题,我们就这样解决了。
下载图片: 在您放置图像的位置创建缓存。如果你需要一个图像,检查它是否在缓存图中,如果它没有下载并放在那里,如果是,请使用它。如果内存已满,请删除缓存中最旧的图像,然后重试。
其他资源图片: 只要你能看到它们就把它们留在内存中,如果你看不到它们,打破引用,gc会为你做清理。
希望这有帮助。
答案 1 :(得分:1)
这里可能会发生一些事情:
确保您的模拟器使用JRE 1.6作为后备JVM。如果您需要使用来自erlyer JDK的运行时库,请使用-Xbootclasspath:<path-to-rt.jar>
。
然后,在您的应用程序进入您想要查看的状态后,执行%JAVA_HOME%\bin\jmap -dump:format=b,file=heap.bin <pid>
(如果您不知道流程的ID,请使用jps
)
现在您已经获得了JVM堆的转储。您可以使用jhat
(JDK附带,有点难以使用)或某些第三方分析器(我的偏好是YourKit
- 分析它 - 它是商业的,但它们有时间限制的eval许可证)< / p>
答案 2 :(得分:1)
我在Java DTV上与LWUIT有类似的问题。当你不再需要它们时,你是否尝试刷新图像(getAWTImage()。flush())?
答案 3 :(得分:1)
尽可能使用EncodedImage
和资源文件(资源文件默认使用EncodedImage
。请阅读javadoc。其他注释也是正确的,你需要实际观察内存量,甚至高RAM Android / iOS设备使用多个图像时内存不足。
避免缩放,有效消除EncodedImage
。
答案 4 :(得分:0)
你有没有想过这样的事实,即可能多次从JAR加载相同的图像会导致创建许多单独的图像对象(具有相同的内容),而不是重复使用每个单独的图像一个实例?这是我的第一个猜测。