【问题标题】:Avoiding out of memory in Codename One避免代号一中的内存不足
【发布时间】:2017-03-06 05:32:18
【问题描述】:

我的情况与this SO question 中描述的情况相同。事实上,我的应用程序很大程度上依赖于URLImage,并且还使用 SidePanel 进行导航。过了一会儿,当我按下后退按钮(Android)时,由于引发 OOM,它变得无法使用。

所以我需要建议来避免这些 OOM 错误。在上面提到的问题中给出了第一个建议,即不要传递对先前表单中任何元素的引用。

确实,我传递了整个表单,因为我想知道从哪里调用“通用”下一个表单(知道当用户单击后退按钮时该去哪里)。所以我改变了它,现在通过表单的类(myForm.getClass())。但是,性能监视器仍然显示超过 200 MB 作为“图像内存开销”。

所以问题可能出在其他地方,因为我还需要传递自定义对象。事实上,我有一个表格 A,它列出了 InfiniteScrollAdapter 中的所有报告。报告是从服务器获取的。然后当用户单击一行时,它会以另一个表单 (B) 打开选定的报告详细信息(日期、图像、位置...),最后如果用户单击图像或位置,它会打开另一个表单带有大尺寸的图像或该位置的谷歌地图。

如果无法传递这些报告,我该怎么办,或者问题真的来自这些传递的引用?

非常感谢任何帮助;-)

【问题讨论】:

    标签: java codenameone


    【解决方案1】:

    我猜您正在使用有问题的图像,而且其中太多没有发布它们。一个好用的工具是内存分析器,我使用 NetBeans 中的那个,它允许您挖掘分配堆栈并查看哪个代码分配了哪个内存块。

    我还建议阅读developer guide graphics sectionperformance section(也讨论内存)中的各种类型的图像。总而言之,请确保您的图像尺寸正确并且是EncodedImage 或这些的变体。您可能想要unlock() 未使用的编码图像,以便 GC 可以更积极地处理它们。

    一旦您将泄漏范围缩小到一组特定的图像,就应该更容易就如何管理这个问题提供具体建议。

    【讨论】:

    • 好的,感谢 Shai 的指导。我将再次查看开发人员指南;-)。仅供参考,使用的图像是低质量的(小于 200k)。但我会确保它们都是 EncodedImage ,因为到目前为止我还没有注意到这一点。我会及时通知你的!
    • 在查询该 OOM 期间,我遇到了一个奇怪的问题:如果我在应用程序显示下一个表单(主表单)时启动我的应用程序时没有启动画面,它需要大约 90MB 的“图像内存开销”。但是如果我用启动画面启动它,那么当显示主窗体时,应用程序现在需要 120MB 的“图像内存开销”。我所有表单共享的唯一内容是每个表单从前一个表单接收的主题资源。主题是否被视为对先前表单元素的引用?
    • 在主窗体上,我有一张地图,在上面我添加了一个 3MB 的透明雷达图像 png(宽度 = 高度 = 4000 像素)。它已作为多图像导入。如果我删除它,那么主窗体上的图像内存开销会下降到 ~60MB,并且 OOM 在设备上消失了。 @Shai 你认为手动绘制雷达值得吗(Graphics,...)?
    • 有几件事可能会触发这种情况。多图像仅以一种分辨率在 RAM 中,但在 res 文件中,它以多种分辨率存储,并且 res 文件可能会一遍又一遍地加载,从而触发此开销。你打电话给Resources.open之类的东西吗?
    • 如果没有createFromImage,它可能会更好地工作,对于从多图像返回的图像,您可以向下转换为编码图像。 4000x4000 可能有点多...
    猜你喜欢
    • 2015-05-14
    • 1970-01-01
    • 1970-01-01
    • 2020-03-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-12-23
    • 2013-10-04
    相关资源
    最近更新 更多