Java 垃圾收集器从不删除对象
这段代码中的问题是,垃圾收集器(GC)永远不会删除产品引用的对象。我可以通过在Eclipse的调试器中将对象视为活动实例来验证这一点Java 垃圾收集器从不删除对象,java,garbage-collection,Java,Garbage Collection,这段代码中的问题是,垃圾收集器(GC)永远不会删除产品引用的对象。我可以通过在Eclipse的调试器中将对象视为活动实例来验证这一点 public static List<ConditionalProbabilityTable> sumOut(List<ConditionalProbabilityTable> factorization, List<Variable> varsToSumOut) { List<ConditionalProbab
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;
}
解决方案
按照@8472使用内存分析器的建议,我可以在YourKit内存快照中识别product
所指向的对象。令人惊讶的是,在for循环之后,该对象消失了!这意味着调试器可能确实以某种方式持有该对象(正如该线程中的其他调试器所建议的那样),从而阻止GC删除该对象。这让我感到惊讶,因为我以前在类似的上下文中运行过一个小示例,而调试器在该示例中没有保存对象。我不明白为什么它不能保持那个时间和这个时间,但无论如何,它似乎是调试器的错误。
感谢大家的支持。使用内存分析器,创建堆转储,查找有问题的对象,检查这些对象到gc根的路径
具体步骤取决于探查器/转储分析器工具。ConditionalProbabilityTableOperation的内部结构是什么。边际化()?是否
ConditionalProbabilityTableOperation。边际化
保留对产品的引用
?如何构建“边际化”?您是否使用产品中的任何成员参考资料?谢谢您的帮助。我编辑了帖子,添加了条件概率表操作。边缘化代码。我试图在任何地方找到对产品的任何引用,但我找不到。Eclipse调试器可以分析运行时并找到对象引用所在的位置。谢谢你的建议,@the8472。事实上,在使用YourKit之前,我已经尝试过这个方法(虽然我使用的方法非常简单,但我对这些技术没有深入的了解)。这里的问题是我不知道我应该追踪哪个物体。在转储中,我会有很多ConditionalProbabilityTable
对象,但我找不到一种方法来检测与for循环中的产品
相关的特定对象。您对此有什么想法吗?使用工具包,您可以为该类列出指向GC根的组合路径。如果该特定循环与所有其他对象不同,则执行线程中的局部变量应显示为根之一。根据您的建议,我可以在您的工具包内存快照中识别product
所指的对象。令人惊讶的是,在for循环之后,该对象消失了!这意味着调试器可能确实以某种方式持有对象,阻止GC删除它。这让我感到惊讶,因为我在类似情况下运行了一个小示例,而调试器在该示例中没有保存对象。我不明白为什么它不能保持那个时间和这个时间,但无论如何,它似乎是调试器的错误。我现在要合上这条线。谢谢
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;
}