垃圾收集器永远不会删除对象

时间:2016-01-07 05:29:20

标签: java garbage-collection

此代码中的问题是垃圾收集器(GC)永远不会删除 product 引用的对象。我可以通过在Eclipse的调试器中将对象视为活动实例来验证这一点。

RewriteBase /hooks/

如果我没有错, product 指向的对象将保持活跃状态​​,因为对它的一些引用(或者可能是产品成员的引用)也是活着的。但我找不到这样的参考(如果需要我可以添加更多代码)。

我的目标是摆脱产品指向的对象。

修改

遵循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

解决方案

按照@8472建议使用内存分析器,我可以在YourKit内存快照中识别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; } 指向的对象。令人惊讶的是,在for循环之后,该对象消失了!这意味着可能调试器确实以某种方式持有对象(正如此线程中的其他人所建议的那样),停止GC移除它。这对我来说是令人惊讶的,因为我已经在类似上下文中的一个小例子之前运行,并且调试器在该示例中没有保持该对象。我无法理解为什么它没有占用这个时间并保持在这个时间,但无论如何它似乎是调试器的错误。 谢谢大家的支持。

1 个答案:

答案 0 :(得分:0)

使用内存分析器,创建堆转储,查找有问题的对象,检查这些对象的gc根路径。

具体步骤取决于探查器/转储分析器工具。