此代碼中的問題是垃圾收集器(GC)永遠不會刪除由產品引用的對象。我可以通過在Eclipse的調試器中將該對象視爲活動實例來驗證此情況。垃圾收集器永遠不會刪除對象
public static List<ConditionalProbabilityTable> sumOut(List<ConditionalProbabilityTable> factorization, List<Variable> varsToSumOut) {
List<ConditionalProbabilityTable> newFactorization = new ArrayList<>(factorization);
for (Variable varToSumOut : varsToSumOut) {
List<ConditionalProbabilityTable> relevantCpts = Inference.getAllCptsContaining(newFactorization, varToSumOut);
ConditionalProbabilityTable product = Inference.multiplyAll(relevantCpts);
ConditionalProbabilityTable marginal = ConditionalProbabilityTableOperation.marginalize(product, varToSumOut);
newFactorization.removeAll(relevantCpts);
newFactorization.add(marginal);
}
return newFactorization;
}
如果我沒看錯的,由產品所指向的對象被保持活着,因爲一些參考吧(或者產品的成員的引用)也是活的。但我找不到這樣的參考(如果需要,我可以添加更多的代碼)。
我的目標是擺脫產品指出的對象。
編輯
遵循ConditionalProbabilityTableOperation.marginalize
代碼:
public static ConditionalProbabilityTable marginalize(ConditionalProbabilityTable cpt, Variable variable) {
ConditionalProbabilityTable marginalCpt = new ConditionalProbabilityTable();
// Determine the scope of the new CPT.
List<Variable> marginalCptLeftVariables = new ArrayList<>();
marginalCptLeftVariables.addAll(cpt.getLeft());
marginalCptLeftVariables.remove(variable);
marginalCpt.addAllToLeft(marginalCptLeftVariables);
List<Variable> marginalCptRightVariables = new ArrayList<>();
marginalCptRightVariables.addAll(cpt.getRight());
marginalCptRightVariables.remove(variable);
marginalCpt.addAllToRight(marginalCptRightVariables);
// Summation loop
int j = 0;
int[] assignments = new int[cpt.getNumberOfVariables()];
int numberOfRowsInMarginal = marginalCpt.getNumberOfRows();
List<Double> marginalValues = new ArrayList<>(Collections.nCopies(numberOfRowsInMarginal, 0.0));
for (int i = 0; i < cpt.getNumberOfRows(); i++) {
marginalValues.set(j, marginalValues.get(j) + cpt.getValue(i));
for (int l = 0; l < cpt.getNumberOfVariables(); l++) {
assignments[l] = assignments[l] + 1;
int lVarCard = cpt.getVariable(l).getCardinality();
if (assignments[l] == lVarCard) {
assignments[l] = 0;
j = j - (lVarCard - 1) * marginalCpt.getStride(cpt.getVariable(l));
} else {
j = j + marginalCpt.getStride(cpt.getVariable(l));
break;
}
}
}
marginalCpt.setValues(marginalValues);
return marginalCpt;
}
解決方案
繼@使用內存分析器,我可以識別由product
在YourKit指向的對象the8472建議內存快照。令人驚訝的是,在for循環之後,該對象消失了!這意味着可能調試器確實以某種方式保持對象(如本線程中的其他人所建議的那樣),停止GC去除它。對我來說,這是令人驚訝的,因爲我已經在類似上下文中的一個小例子之前運行,並且調試器在該例子中沒有保留該對象。我不明白爲什麼它沒有保持這個時間,並堅持在這一個,但無論如何,它似乎是調試器故障。 非常感謝您的支持。
ConditionalProbabilityTableOperation.marginalize()的內部是什麼? – Wash
'ConditionalProbabilityTableOperation.marginalize'是否保留對'product'的引用? –
'邊際'如何構建?您是否在使用產品中的任何成員參考? –