【发布时间】:2018-02-19 00:51:20
【问题描述】:
正如 Hans Boehm 在 Google I/O '17 演讲“How to Manage Native C++ Memory in Android”中建议我使用 PhantomReferenceclass 来确保正确删除本地对等点。
在18 min 57 sec 的链接视频中,他展示了一个将自身注册到PhantomReference 类的对象的示例实现。这个PhantomReference 课程,他随后在19 min 49 sec 显示。所以我为我的示例对象复制了他的方法。见下文。
虽然这种方法效果很好,但它无法扩展。我需要创建相当多的对象,但我还没有找到创建基类的方法(无论是为我的对象还是PhantomReference 基类),它将接受任何对象并正确处理本机删除。
我怎样才能创建一个通用基础PhantomReference 类,它可以在提供的对象上调用本机静态方法?
我尝试转换 PhantomReference 泛型,但原生静态删除方法阻碍了实现。
我的WorkViewModel
import android.databinding.*;
public class WorkViewModel extends BaseObservable
{
private long _nativeHandle;
public WorkViewModel(Database database, int workId)
{
_nativeHandle = create(database.getNativeHandle(), workId);
WorkViewModelPhantomReference.register(this, _nativeHandle);
}
private static native long create(long databaseHandle, int workId);
static native void delete(long nativeHandle);
@Bindable
public native int getWorkId();
public native void setWorkId(int workId);
}
我的WorkViewModelPhantomReference
import java.lang.ref.*;
import java.util.*;
public class WorkViewModelPhantomReference extends PhantomReference<WorkViewModel>
{
private static Set<WorkViewModelPhantomReference> phantomReferences = new HashSet<WorkViewModelPhantomReference>();
private static ReferenceQueue<WorkViewModel> garbageCollectedObjectsQueue = new ReferenceQueue<WorkViewModel>();
private long _nativeHandle;
private WorkViewModelPhantomReference(WorkViewModel workViewModel, long nativeHandle)
{
super(workViewModel, garbageCollectedObjectsQueue);
_nativeHandle = nativeHandle;
}
public static void register(WorkViewModel workViewModel, long nativeHandle)
{
phantomReferences.add(new WorkViewModelPhantomReference(workViewModel, nativeHandle));
}
public static void deleteOrphanedNativePeerObjects()
{
WorkViewModelPhantomReference reference;
while((reference = (WorkViewModelPhantomReference)garbageCollectedObjectsQueue.poll()) != null)
{
WorkViewModel.delete(reference._nativeHandle);
phantomReferences.remove(reference);
}
}
}
【问题讨论】:
-
我立即相信这种方法无法扩展。但我不明白您的第二个问题,即您“还没有找到创建基类的方法……它可以接受任何对象并正确处理本机删除”。您有一个由两个类组成的有效解决方案。假设的基类应该解决什么问题以及如何解决?
-
@Holger 感谢您的回复。请解释一下规模问题?这就是我试图用一个假设的基类来解决的问题。我有很多这样的对象,我必须为每个对象创建第二个幻像类。有了一个基类,我想解决我不需要创建一个额外的类或者让它变得简单到我只需要定义类型。
-
等等——你为每个你创建的对象创建一个新的幻像类?或者你所说的“每一个”是什么意思?
-
这正是我目前所做的(我上面问题的第三段)。所以这就是为什么我问这个问题是否有更好的方法来做到这一点。
-
看起来你混淆了对象和类。我不明白为什么要为每个 object 创建一个新的 class。我想,对于每个具有不同
delete方法的不同 class,您需要一个新的 class,对吗?对于每个需要清理的 object,您需要另一个新的幻像 object。当我第一次阅读“不扩展”时,我想,您是在谈论这种设计的性能不佳,这部分与您必须创建的对象有关,但是,您似乎主要是在谈论代码复杂性,这与类有关。后者可能是可以解决的
标签: java android memory-management phantom-reference