Что это означает, когда в анализе дампа кучи на объект ссылается только «этот $ 0»? - PullRequest
0 голосов
/ 03 августа 2020

Я проанализировал дамп кучи, чтобы выяснить, почему несколько экземпляров определенного класса все еще находятся в памяти даже после того, как их назначение закончилось. Я обнаружил, что единственной ссылкой на каждый экземпляр является сам объект.

ScheduleWindow # 1 имеет «этот $ 0 в ScheduleWindow $ 1 # 1» в качестве единственной ссылки.

ScheduleWindow # 2 имеет "this $ 0 в ScheduleWindow $ 1 # 2" в качестве единственной ссылки.

ScheduleWindow # 3 имеет "this $ 0 в ScheduleWindow $ 1 # 3" в качестве единственной ссылки.

...

Что значит иметь такие ссылки? ScheduleWindow также не является внутренним классом.

PS Потерпите, пожалуйста, со мной, что я не опубликовал фактический код, потому что я не могу опубликовать фактический код по юридическим причинам.

Ответы [ 2 ]

1 голос
/ 03 августа 2020

Внутренний класс всегда имеет неявную ссылку на внешний класс, который отображается как «этот $ 0». Возьмем для примера этот код:

public class Test {

  String test;

  // inner class has a this$0 reference to its outer / parent object
  public class Inner {
    String inner;

    void bar(Object anonymous) {
      // the debugger screenshot is taken here
      System.out.println();
    }
  }

  void foo() {
    // create an instance of Inner and pass an anonymous inner class to it
    new Inner().bar(new Runnable() {
      public void run() {}
    });
  }

  public static void main(String[] args) {
    new Test().foo();
  }
}

Если вы установите точку останова в «bar», стек вызовов будет: main -> foo -> bar. Отладчик показывает следующие переменные:

введите описание изображения здесь

Bar - это метод во внутреннем классе (id 22), который указывает на внешний класс (id 24) через этот $ 0.

Также существует анонимный внутренний класс в Тест, который называется Тестом $ 1. Он также имеет тот же указатель.

Если вы определяете Inner как c внутренний класс, этот указатель отсутствует.

Просматривая ссылку «ScheduleWindow $ 1», вы, вероятно, имеете анонимный класс, определенный где-то там (например, Runnable в приведенном выше примере), и этот экземпляр имеет ссылку this $ 0 на ScheduleWindow.

0 голосов
/ 03 августа 2020

Пожалуйста, просмотрите все поля статистики c в этом классе. Также лучше сделать класс не имеющим состояния, если вы хотите, чтобы он легко освобождался в куче памяти. Я сталкивался с подобными проблемами раньше. Плохой дизайн в Singleton Util.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...