Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/153.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 防止过早收集垃圾_Java_C++_Garbage Collection_Java Native Interface_Swig - Fatal编程技术网

Java 防止过早收集垃圾

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

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

以下的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);}