2016-01-07 2 views
-1

Проблема в этом коде заключается в том, что объект, на который ссылается продукт, никогда не удаляется сборщиком мусора (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; 
} 

Если я не ошибаюсь, объект указываемого продукт в настоящее время хранится в живых, потому что некоторые ссылки на него (или, может быть ссылкой на члена продукта) также жив. Но я не мог найти такую ​​ссылку (я могу добавить больше кода, если это необходимо).

Моя цель - избавиться от предмета, на который указывает продукт.

EDIT

Следит код 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; 
} 

Решение

После @ the8472 предложение использовать профайлер памяти я мог бы идентифицировать объект, на который указывает product в YourKit моментальный снимок памяти. Удивительно, но после цикла for этот объект исчез! Это означает, что, возможно, отладчик действительно каким-то образом удерживал объект (как это было предложено другими в этом потоке), останавливая GC для его удаления. Это было удивительно для меня, так как я работал до небольшого примера в аналогичном контексте, и отладчик не удерживал объект в этом примере. Я не могу понять, почему это не удержит это время и держится в этом, но в любом случае это похоже на ошибку отладчика. Спасибо всем за вашу поддержку.

+1

Что такое внутренние для ConditionalProbabilityTableOperation.marginalize()? – Wash

+0

Поддерживает ли 'ConditionalProbabilityTableOperation.marginalize' ссылку на' product'? –

+0

Как создается «маргинальный»? Используете ли вы какие-либо ссылки на членство от продукта? –

ответ

0

Используйте профилировщик памяти, создайте кучу кучи, ищите объект (ы), о котором идет речь, изучите пути к корням gc из этих объектов.

Точные этапы зависят от инструмента анализатора профайлера/дампа.

+0

Спасибо за ваше предложение @ the8472. На самом деле, я пробовал это, прежде чем использовать YourKit (я использовал очень простой способ, я не имею глубокого понимания этих методов). Проблема здесь в том, что я не могу определить, какой объект я должен отслеживать. В дампе у меня было бы много объектов ConditionalProbabilityTable, но я не мог найти способ обнаружить конкретный, который связан с этим «продуктом» внутри цикла for. У вас есть мысли по этому поводу? – jhonatanoliveira

+0

с помощью yourkit вы можете иметь * комбинированные пути к корням GC *, перечисленные для этого класса. Если в этом конкретном цикле есть что-то особенное, а не все другие объекты, то локальная переменная в исполняемом потоке должна отображаться как один из корней. – the8472

+0

Следуя вашему предложению, я смог идентифицировать объект, указанный «продуктом» в снимке памяти MyKit. Удивительно, но после цикла for этот объект исчез! Это означает, что возможно, что отладчик действительно каким-то образом удерживал объект, останавливая GC для его удаления. Это было удивительно для меня, так как я выполнил небольшой пример в подобной ситуации, и отладчик не удерживал объект в этом примере. Я не могу понять, почему это не удержит это время и держится в этом, но в любом случае это похоже на ошибку отладчика. Я сейчас закрою эту тему. Благодарю. – jhonatanoliveira

Смежные вопросы