Исключение нулевого указателя - это индикатор того, что вы используете объект, не инициализируя его.
Например, ниже - класс ученика, который будет использовать его в нашем коде.
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 ");
}
}
}
Выведите "кучу" и осмотрите ее.
я уверен, что существует больше чем один способ сделать это, но здесь простой. Это описание для MS Windows, но подобные шаги могут быть сделаны в других операционных системах.
Вот пример:
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. Объект; действительно означает объект Объекта типа [] .
Попробуйте Память Eclipse Анализатор. Это покажет Вам для каждого объекта, как это подключено к корню GC - объект, который не собран "мусор", потому что это сохранено JVM.
Видят http://dev.eclipse.org/blogs/memoryanalyzer/2008/05/27/automated-heap-dump-analysis-finding-memory-leaks-with-one-click/ для получения дополнительной информации о том, как ЦИНОВКА Eclipse работает.
Я посмотрел бы на Наборы (особенно статические) в Ваших классах (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 или некоторый другой набор имеют ссылку на тот объект, он не будет собран "мусор".
Никакая серебряная пуля там, необходимо использовать профилировщика для идентификации наборов, которые содержат те ненужные объекты и находят место в коде, куда они должны были быть удалены. Как JesperE заявил, статические наборы являются первым местом для взгляда на.
Внимательно наблюдайте за статическими контейнерами. Любые объекты в статическом контейнере останутся, пока класс загружается.
Редактирование: удаленный неправильный комментарий по WeakReference.
Один очевидный кандидат является объектами с финализаторами. Они могут задержаться, в то время как их завершать метод назван. Они должны быть собраны, затем завершены (обычно только с единственным потоком финализатора) и затем собраны снова.
Также знать, что можно получить OOME, потому что gc не удалось собрать достаточно памяти, несмотря на там то, чтобы на самом деле быть достаточно, чтобы объектный запрос был создан. Иначе производительность сточилась бы в землю.
Я просто прочитал статью об этом, но я сожалею, что не могу помнить где. Я думаю, что это, возможно, был в книге "Эффективный Java". Если я найду ссылку, то я обновлю свой ответ.
два важных урока, которые это обрисовало в общих чертах:
1) Последние методы говорят gc, что сделать, когда это отбирает объект, но это не просит, чтобы это сделало так, и при этом нет способа потребовать, чтобы это сделало.
2) современный эквивалент "утечки памяти" в неуправляемых средах памяти, ссылки, о которых забывают. Если Вы не установите все ссылки на объект к пустой указатель , когда Вы будете сделаны с ним, объект будет никогда , отобраны. Это является самым важным при реализации собственного вида Набора или собственной обертки, которая управляет Набором. Если у Вас будут пул или стек или очередь, и Вы не устанавливаете блок на пустой указатель , когда Вы "удалите" объект из набора, то блок, в котором был объект, поддержит тот объект, пока тот блок не установлен относиться к другому объекту.
правовая оговорка: Я знаю, что другие ответы упомянули это, но я пытаюсь предложить больше детали.
Наборы были уже упомянуты. Другое дефицитное местоположение - то, при использовании нескольких ClassLoaders поскольку старый classloader может не мочь быть собранным "мусор", пока все ссылки не пошли.
Также помехи проверки - они противны. Платформы журналирования могут сохранить вещи открытыми, который может сохранить ссылки в пользовательском appenders.
Вы разрешали проблему?
Я использовал профилировщика 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
Некоторые предложения:
Если Вы получаете ошибки OOM на собравшем "мусор" языке, это обычно означает, что существует некоторая память, не считавшая коллектором. Возможно, Ваши объекты содержат ресурсы не-Java? если так, затем у них должен быть некоторый 'близкий' метод, чтобы удостовериться, что ресурс выпущен, даже если объект Java не собран достаточно скоро.