防止过早收集垃圾

Prevent premature garbage collection

本文关键字:      更新时间:2023-10-16

我遇到了过早垃圾收集的问题。我在SWIG文档中找到了一个很好的解决方案来解决此类问题。但我遇到了一个问题,因为我有一个静态工厂方法,无法访问非静态引用字段。

将推荐的SWIG解决方案应用于以下的C++代码

struct Child {
};
struct Parent {
  static Parent* create(Child& child);
};

获得像一样的Java代码

public static Parent create(Child child) {
  long cPtr = SampleJNI.Parent_create(getCPtrAndAddReference(child), child);
  return (cPtr == 0) ? null : new Parent(cPtr, false);
}

由于Parent.create(Child child)是静态的,但Parent.getCPtrAndAddReference(Child child)不是静态的,因此此代码已损坏。我正在考虑两种解决方案中的一种。

第一个是找到生成类似的东西的方法

public static Parent create(Child child) {
  long cPtr = SampleJNI.Parent_create(Child.getCPtr(child), child);
  return (cPtr == 0) ? null : new Parent(cPtr, false, child)/* call of alternative constructor created with typmap(javabody) */;
}

但我不知道怎么做。

第二种解决方案是通过SetObjectField调用在JNI侧实现分配。一般来说,我知道该怎么做,但如果可能的话,我更喜欢第一种解决方案。

试试这样的东西:

%newobject Parent::create;
%typemap(javacode) Parent %{
  private Child childReference;
%}
%typemap(javaout) Parent* create(Child&) {
    long cPtr = $jnicall;
    if (cPtr == 0) {
        return null;
    } else {
        Parent p = new Parent(cPtr, $owner);
        p.childReference=child;
        return p;
    }
}

这将在Parent中添加字段,该字段将存储对子项的引用,并在创建时保存引用。

%newobject说java在垃圾收集该项时删除C对象。别忘了这件事,否则你会有内存泄漏的。

相关文章:
  • 没有找到相关文章