Исключение нулевого указателя - это индикатор того, что вы используете объект, не инициализируя его.
Например, ниже - класс ученика, который будет использовать его в нашем коде.
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 ");
}
}
}
Этот код должен разрешить его:
public class TestInvisibleObject{
public static class PrintWhenFinalized{
private String s;
public PrintWhenFinalized(String s){
System.out.println("Constructing from "+s);
this.s = s;
}
protected void finalize() throws Throwable {
System.out.println("Finalizing from "+s);
}
}
public static void main(String[] args) {
try {
PrintWhenFinalized foo = new PrintWhenFinalized("main");
} catch (Exception e) {
// whatever
}
while (true) {
// Provoke garbage-collection by allocating lots of memory
byte[] o = new byte[1024];
}
}
}
На моей машине (jdk1.6.0_05) это печатает:
Построение из основного
Завершение от основного
, Таким образом, это похоже, проблемы были решены.
Примечание, что использование System.gc () вместо цикла не заставляет объект быть собранным по некоторым причинам.
В статье говорится что:
... эффективное внедрение JVM вряд ли обнулит ссылку, когда это выйдет из объема
, я думаю, что это происходит из-за таких ситуаций:
public void doSomething() {
for(int i = 0; i < 10 ; i++) {
String s = new String("boo");
System.out.println(s);
}
}
Здесь, та же ссылка используется "эффективной JVM" в каждом объявлении Строки s, но будет 10 новых Строк в "куче", если GC не умрет.
В примере статьи я думаю, что ссылка на нечто сохраняет в стеке, потому что "эффективная JVM" думает , который вероятен, что другой объект нечто будет создан и, если так, это будет использовать ту же ссылку. Мысли???
public void run() {
try {
Object foo = new Object();
foo.doSomething();
} catch (Exception e) {
// whatever
}
while (true) { // do stuff } // loop forever
}
я также выполнил следующий тест с профилированием:
public class A {
public static void main(String[] args) {
A a = new A();
a.test4();
}
public void test1() {
for(int i = 0; i < 10 ; i++) {
B b = new B();
System.out.println(b.toString());
}
System.out.println("b is collected");
}
public void test2() {
try {
B b = new B();
System.out.println(b.toString());
} catch (Exception e) {
}
System.out.println("b is invisible");
}
public void test3() {
if (true) {
B b = new B();
System.out.println(b.toString());
}
System.out.println("b is invisible");
}
public void test4() {
int i = 0;
while (i < 10) {
B b = new B();
System.out.println(b.toString());
i++;
}
System.out.println("b is collected");
}
public A() {
}
class B {
public B() {
}
@Override
public String toString() {
return "I'm B.";
}
}
}
и приходят к заключениям:
teste1-> b собран
, teste2-> b невидим
, teste3-> b невидим
, teste4-> b собран
..., таким образом, я думаю, что в циклах JVM не создает невидимые переменные, когда цикл заканчивается, потому что маловероятно, что они будут объявлены снова вне цикла.
Какие-либо Мысли??
У Вас действительно было бы так много кода для анализа? В основном я могу только видеть этот являющийся значительной проблемой для очень продолжительных методов - которые являются обычно просто теми наверху стопки каждого потока.
я не был бы вообще удивлен, если это откреплено в данный момент, но я не думаю, что это, вероятно, будет столь значительно, как Вы, кажется, боитесь.