我正在使用Jess和FixThreadPool创建几个Rete引擎,可用于评估并行模式下系统的性能。每个Rete引擎独立于其他引擎运行,并将包含系统设计的Java对象作为输入,并输出包含其性能指标的另一个Java对象。
在评估每个系统之前,我将Rete引擎重置为原始状态。但是,当我的程序运行时,RAM内存不断堆积,存储了越来越多的jess.Value对象。
这是我用来将Jess与Java接口的类:
public class Variant {
private final Object value;
private final String type;
public Variant(Object value) {
this.value = cast2JavaObject(value);
this.type = (this.value instanceof List) ? "multislot" : "slot";
}
public Object getValue() {
return value;
}
public String getType() {
return type;
}
private Object cast2JavaObject(Object value) {
try {
if (value instanceof Value) {
return castJessValue((Value) value);
} else {
return value;
}
} catch (Exception e) {
System.out.println(e.getMessage());
e.printStackTrace();
return null;
}
}
private synchronized Object castJessValue(Value value) throws Exception {
if (value.type() == RU.LIST) {
List list = new ArrayList<Object>();
list.addAll(Arrays.asList((Object[]) RU.valueToObject(Object.class, value, null)));
return list;
} else {
return RU.valueToObject(Object.class, value, null);
}
}
public Value toJessValue() throws Exception {
Object val;
if (value instanceof List) {
val = ((List) value).toArray();
} else {
val = value;
}
return RU.objectToValue(val.getClass(), val);
}
}
Variant中包含的Object是否可能指向jess.Value的内容,因此当我调用rete.reset()时GC不会收集它们?
答案 0 :(得分:0)
我认为如果在构造函数中传递的对象(无论是jess.Value还是普通的POJO)引用一个或多个jess.Value,这将是可能的。你的cast2JavaObject和RU.valueToObject都不是递归的和内省的。
但是,如果包含 jess.Value对象怎么办?它们是Java对象的装饰,即使它们被打开,堆也会单独堆积裸露的对象,只是速度较慢。
如果使用存储/提取,除了重置之外,我还会调用clearStorage。
我建议进行一项缩小OOM问题的实验。而不是重置,重新创建Rete对象。如果问题仍然存在,我敢说这是你应用程序中的其他一些角落。