Как я могу выяснить то, что держится за неосвобожденные объекты?

Исключение нулевого указателя - это индикатор того, что вы используете объект, не инициализируя его.

Например, ниже - класс ученика, который будет использовать его в нашем коде.

public class Student {

    private int id;

    public int getId() {
        return this.id;
    }

    public setId(int newId) {
        this.id = newId;
    }
}

Приведенный ниже код дает вам исключение с нулевым указателем.

public class School {

    Student obj_Student;

    public School() {
        try {
            obj_Student.getId();
        }
        catch(Exception e) {
            System.out.println("Null Pointer ");
        }
    }
}

Поскольку вы используете Obj_Student, но вы забыли инициализировать его, как в правильном коде, показанном ниже:

public class School {

    Student obj_Student;

    public School() {
        try {
            obj_Student = new Student();
            obj_Student.setId(12);
            obj_Student.getId();
        }
        catch(Exception e) {
            System.out.println("Null Pointer ");
        }
    }
}
14
задан Gray 6 November 2013 в 22:29
поделиться

11 ответов

Выведите "кучу" и осмотрите ее.

я уверен, что существует больше чем один способ сделать это, но здесь простой. Это описание для MS Windows, но подобные шаги могут быть сделаны в других операционных системах.

  1. Установка JDK, если у Вас уже нет его. Это идет с набором аккуратных инструментов.
  2. Запускают приложение.
  3. Открытый диспетчер задач и находит идентификатор процесса (PID) для java.exe (или безотносительно исполняемого файла, который Вы используете). Если PID не показывают по умолчанию, используйте Представление> Избранные Столбцы... для добавления их.
  4. Дамп "куча" с помощью jmap.
  5. Запускаются сервер jhat на файле, который Вы генерировали, и откройте свой браузер для http://localhost:7000 (порт по умолчанию 7000). Теперь можно ли просмотреть тип, Вы интересуетесь и информация как количество экземпляров, что имеет ссылки на них и так далее.

Вот пример:

C:\dump>jmap -dump:format=b,file=heap.bin 3552

C:\dump>jhat heap.bin
Reading from heap.bin...
Dump file created Tue Sep 30 19:46:23 BST 2008
Snapshot read, resolving...
Resolving 35484 objects...
Chasing references, expect 7 dots.......
Eliminating duplicate references.......
Snapshot resolved.
Started HTTP server on port 7000
Server is ready.

Для интерпретации этого полезно понять часть из номенклатура типа массива использование Java - как знание что класс [Ljava.lang. Объект; действительно означает объект Объекта типа [] .

19
ответ дан 1 December 2019 в 06:40
поделиться

Попробуйте Память Eclipse Анализатор. Это покажет Вам для каждого объекта, как это подключено к корню GC - объект, который не собран "мусор", потому что это сохранено JVM.

Видят http://dev.eclipse.org/blogs/memoryanalyzer/2008/05/27/automated-heap-dump-analysis-finding-memory-leaks-with-one-click/ для получения дополнительной информации о том, как ЦИНОВКА Eclipse работает.

9
ответ дан 1 December 2019 в 06:40
поделиться

Я посмотрел бы на Наборы (особенно статические) в Ваших классах (HashMaps являются хорошим местом для запуска). Возьмите этот код, например:

Map<String, Object> map = new HashMap<String, Object>(); // 1 Object
String name = "test";             // 2 Objects
Object o = new Object();          // 3 Objects
map.put(name, o);                 // 3 Objects, 2 of which have 2 references to them

o = null;                         // The objects are still being
name = null;                      // referenced by the HashMap and won't be GC'd

System.gc();                      // Nothing is deleted.

Object test = map.get("test");    // Returns o
test = null;

map.remove("test");               // Now we're down to just the HashMap in memory
                                  // o, name and test can all be GC'd

, пока HashMap или некоторый другой набор имеют ссылку на тот объект, он не будет собран "мусор".

5
ответ дан 1 December 2019 в 06:40
поделиться

Никакая серебряная пуля там, необходимо использовать профилировщика для идентификации наборов, которые содержат те ненужные объекты и находят место в коде, куда они должны были быть удалены. Как JesperE заявил, статические наборы являются первым местом для взгляда на.

3
ответ дан 1 December 2019 в 06:40
поделиться

Внимательно наблюдайте за статическими контейнерами. Любые объекты в статическом контейнере останутся, пока класс загружается.

Редактирование: удаленный неправильный комментарий по WeakReference.

2
ответ дан 1 December 2019 в 06:40
поделиться

Один очевидный кандидат является объектами с финализаторами. Они могут задержаться, в то время как их завершать метод назван. Они должны быть собраны, затем завершены (обычно только с единственным потоком финализатора) и затем собраны снова.

Также знать, что можно получить OOME, потому что gc не удалось собрать достаточно памяти, несмотря на там то, чтобы на самом деле быть достаточно, чтобы объектный запрос был создан. Иначе производительность сточилась бы в землю.

2
ответ дан 1 December 2019 в 06:40
поделиться

Я просто прочитал статью об этом, но я сожалею, что не могу помнить где. Я думаю, что это, возможно, был в книге "Эффективный Java". Если я найду ссылку, то я обновлю свой ответ.

два важных урока, которые это обрисовало в общих чертах:

1) Последние методы говорят gc, что сделать, когда это отбирает объект, но это не просит, чтобы это сделало так, и при этом нет способа потребовать, чтобы это сделало.

2) современный эквивалент "утечки памяти" в неуправляемых средах памяти, ссылки, о которых забывают. Если Вы не установите все ссылки на объект к пустой указатель , когда Вы будете сделаны с ним, объект будет никогда , отобраны. Это является самым важным при реализации собственного вида Набора или собственной обертки, которая управляет Набором. Если у Вас будут пул или стек или очередь, и Вы не устанавливаете блок на пустой указатель , когда Вы "удалите" объект из набора, то блок, в котором был объект, поддержит тот объект, пока тот блок не установлен относиться к другому объекту.

правовая оговорка: Я знаю, что другие ответы упомянули это, но я пытаюсь предложить больше детали.

1
ответ дан 1 December 2019 в 06:40
поделиться

Наборы были уже упомянуты. Другое дефицитное местоположение - то, при использовании нескольких ClassLoaders поскольку старый classloader может не мочь быть собранным "мусор", пока все ссылки не пошли.

Также помехи проверки - они противны. Платформы журналирования могут сохранить вещи открытыми, который может сохранить ссылки в пользовательском appenders.

Вы разрешали проблему?

1
ответ дан 1 December 2019 в 06:40
поделиться

Я использовал профилировщика Java Yourkit ( http://www.yourkit.com ) для оптимизации производительности на java 1.5. Это имеет раздел по тому, как работать над утечками памяти. Я нахожу это полезным.

http://www.yourkit.com/docs/75/help/performance_problems/memory_leaks/index.jsp

можно получить 15-дневную оценку: http://www.yourkit.com/download/yjp-7.5.7.exe

BR,
~A

1
ответ дан 1 December 2019 в 06:40
поделиться

Некоторые предложения:

  • Неограниченные карты используются в качестве кэшей, особенно, когда статичный
  • ThreadLocals в приложениях для сервера, потому что потоки обычно не умирают, таким образом, ThreadLocal не освобожден
  • Интернирование строк (Strings.intern ()), который приводит к груде Строк в PermSpace
1
ответ дан 1 December 2019 в 06:40
поделиться

Если Вы получаете ошибки OOM на собравшем "мусор" языке, это обычно означает, что существует некоторая память, не считавшая коллектором. Возможно, Ваши объекты содержат ресурсы не-Java? если так, затем у них должен быть некоторый 'близкий' метод, чтобы удостовериться, что ресурс выпущен, даже если объект Java не собран достаточно скоро.

0
ответ дан 1 December 2019 в 06:40
поделиться
Другие вопросы по тегам:

Похожие вопросы: