重置后Rete对象不释放值

时间:2014-07-23 20:22:56

标签: java jess

我正在使用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不会收集它们?

1 个答案:

答案 0 :(得分:0)

我认为如果在构造函数中传递的对象(无论是jess.Value还是普通的POJO)引用一个或多个jess.Value,这将是可能的。你的cast2JavaObject和RU.valueToObject都不是递归的和内省的。

但是,如果包含 jess.Value对象怎么办?它们是Java对象的装饰,即使它们被打开,堆也会单独堆积裸露的对象,只是速度较慢。

如果使用存储/提取,除了重置之外,我还会调用clearStorage。

我建议进行一项缩小OOM问题的实验。而不是重置,重新创建Rete对象。如果问题仍然存在,我敢说这是你应用程序中的其他一些角落。