Java 防止过早收集垃圾
我有一个问题,过早的垃圾收集。我在SWIG文档中找到了解决此类问题的好方法。但我遇到了这个问题,因为我有静态工厂方法,非静态参考字段无法访问Java 防止过早收集垃圾,java,c++,garbage-collection,java-native-interface,swig,Java,C++,Garbage Collection,Java Native Interface,Swig,我有一个问题,过早的垃圾收集。我在SWIG文档中找到了解决此类问题的好方法。但我遇到了这个问题,因为我有静态工厂方法,非静态参考字段无法访问 在以下的C++代码中应用推荐的SWIG解决方案 struct Child { }; struct Parent { static Parent* create(Child& child); }; 得到像这样的坏Java代码 public static Parent create(Child child) { long cPtr = Sa
在
以下的C++代码中应用推荐的SWIG解决方案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;
}
}
这将向父项添加字段,该字段将存储对子项的引用,并在创建时保存引用
%newobject
说java在垃圾收集此项时删除C对象。别忘了它,否则你会有内存泄漏。我只用你的结构创建了接口文件,名为swig-c++-java-outdir-outdir-o wrapper.c-package com.example interface.I
(3.0.7版,windows cygwin),它生成了正确的代码:long cPtr=exampleJNI.Parent\u create(Child.getCPtr(Child),Child)代码>。它必须是旧swig版本或接口文件中的其他项。@V-master,谢谢您的回答,但恐怕您误解了我。我的目标是永久缓存child
,而不仅仅是在Parent\u create
调用期间。您可以使用NewGlobalRef
在C代码中保留java对象。这就是你想要的吗?@user2543253,是的,这可能是使用SetObjectField
的替代方法。但是在Java方面解决这个问题会很好,因为JNI解决方案对我来说很容易出错。@user2543253,而且NewGlobalRef
意味着使用DeleteGlobalRef
,但是我希望尽可能多地在JVM上保持内存管理。谢谢,看起来就像我正在寻找的一样。我对您的解决方案做了一些更改:%typemap(javacode)B%{private a childReference;@SuppressWarnings(“未使用”)受保护的B(长cPtr,布尔cMemoryOwn,a childReference){this(cPtr,cMemoryOwn);this.childReference=childReference;}%}%newobject B::create;%typemap(javaout)B::create(A*A){long cPtr=$jnicall;return(cPtr==0)?null:newb(cPtr,$owner,A);}