防止过早的垃圾收集

时间:2015-11-17 08:27:50

标签: java c++ garbage-collection java-native-interface swig

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

将推荐的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端实现分配。我确实知道如何做到这一点,但如果可能的话我宁愿选择第一个解决方案。

1 个答案:

答案 0 :(得分:1)

尝试这样的事情:

%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添加字段,该字段将存储对child的引用,并在创建时保存引用。

%newobject说java在垃圾收集这个项目时删除C对象。不要忘记它,否则你会有内存泄漏。