0

我正在使用 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);
    }
}

变量中包含的对象是否有可能指向 jess.Value 的内容,因此当我调用 rete.reset() 时它们没有被 GC 收集?

4

1 回答 1

0

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

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

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

我建议做一个实验来缩小 OOM 问题。与其重置,不如重新创建 Rete 对象。如果问题仍然存在,我敢说它在您的应用程序的其他角落或缝隙中。

于 2014-07-24T05:11:11.353 回答