gpt4 book ai didi

java - 黑莓 7 : Odd Memory Leak in Root Process

转载 作者:太空宇宙 更新时间:2023-11-04 07:30:46 25 4
gpt4 key购买 nike

我现在正在调查旧版 BB7 应用程序中的内存泄漏问题,该应用程序最初是由不再在公司工作的开发人员为 OS 4.5 开发的。该孔太大,设备会随着时间的推移而退化,并在使用几个小时后使设备处于缓慢状态。它变得更慢,因为可怕的黑色时钟出现在屏幕上,并且频率不断增加,以进行简单的操作。我已经与调试器确认,当垃圾收集器启动时会出现黑色时钟,并且在这些时间间隔内没有发生其他繁重的处理。显然这些自动GC操作并没有缓解内存短缺的问题。

我已经使用 Eclipse 的 BB 插件中的 BlackBerry Objects View 检查了流程应用程序内存。我没有看到此进程中任何类型的实例数量异常。有趣的是,模型中某个类的大量实例似乎存在于根进程 RAM (pid=0) 中,尽管是由该应用进程创建的。它们似乎是由于对保存它们的持久 vector 的迭代而泄漏的(例如:持久存储中只有 100 个实例,但在对持久 vector 进行几次迭代后,根进程 RAM 中就有 2000 个实例。显然,这 1900 个额外实例是已持久化实例的克隆)。打开调试器后,我可以看到实例不断堆积在 RAM 中,并且不会被我在控制台中看到的简短自动 GC 收集,但当我从调试器中手动强制 GC 时,它们会被删除(这需要相当长的运行时间)。

主要嫌疑点是作为单例实例保存在 RuntimeStore 中的 DAO 类(也必须从备用入口点调用)。它保存对保存在 PersistentStore 中的 BigVector 的引用,并包含上述模型类的实例。这是一个缩短的版本:

    public class LeakyDAO { 
private long persistentStoreId;
private long runtimeStoreId;
private PersistentObject persistentObject;
private BigVector bigVector;

private LeakyDAO(long id_p, long id_r) {
persistentStoreId = id_p;
runtimeStoreId = id_r;
persistentObject = PersistentStore.getPersistentObject(persistentStoreId);
Object o = persistentObject.getContents();

if(o instanceof BigVector){
bigVector = (BigVector) o;
} else {
bigVector = new BigVector();
persistentObject.setContents(bigVector);
}
}

public static synchronized LeakyDAO getInstance(long idPersist, long idRuntime) {
RuntimeStore rs = RuntimeStore.getRuntimeStore();
LeakyDAO dao = (LeakyDAO) rs.get(idRuntime);
if (dao == null) {
dao = new LeakyDAO(idPersist, idRuntime);
try {
rs.put(idRuntime, dao);
} catch (IllegalArgumentException e) {
//Already exists
}
}
return dao;
}

public synchronized Object get(int index) {
return ObjectGroup.expandGroup(bigVector.elementAt(index));
}


public synchronized void insertAt(int index, Persistable p) {
ObjectGroup.createGroupIgnoreTooBig(p);
if (index >= bigVector.size()) {
bigVector.addElement(p);
} else {
bigVector.insertElementAt(p, index);
}
persistentObject.setContents(bigVector);
persistentObject.commit();
}
}

我忽略的这门课有什么可怕的错误吗?此时,我还无法确认这些实例实际上是问题的原因,因为应用程序在插入调试器时的行为非常不同。但是,由于操作系统中的错误(或已知行为),某些实例在重复调用 getinsertAt 后是否会被泄漏?

<小时/>

更新
自动垃圾收集的问题和一些 OutOfMemoryErrors 仅在调试器打开时才会出现。当它不在 Debug模式下时,自动GC确实按预期工作,所以我认为调试器有问题。在对象 View 中我也进行了一些重置。

最佳答案

我看到每个“get”都会调用expandGroup,每个插入都会调用createGroup。我认为这些函数并没有试图提高效率。这意味着他们每次都会复制对象,即使没有必要。

使用这些对象的代码是否修改了它们?或者,如果有修改,您能否缩小范围,并仅在这些情况下使用“getMutable”?如果您可以执行其中任一操作,您将能够从 insertAt 函数中删除“createGroup”,并从 get 函数中删除“expandGroup”,并保存对象副本。

关于java - 黑莓 7 : Odd Memory Leak in Root Process,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17743109/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com