Когда вы компилируете свою программу, например, используя javac
и запустите команду javap -c PrincipalClass
(javap
- это команда, поставляемая с JDK), вы увидите следующий вывод:
Compiled from "PrincipalClass.java"
public class PrincipalClass {
public PrincipalClass();
Code:
0: aload_0
1: invokespecial #1 // Method java/lang/Object."<init>":()V
4: return
public static void main(java.lang.String[]);
Code:
0: invokestatic #2 // Method returnStringMethod:()Ljava/lang/String;
3: pop
4: return
public static java.lang.String returnStringMethod();
Code:
0: ldc #3 // String Hello, Java world!
2: areturn
}
Важной частью является метод main
, состоящий из инструкций байт-кода invokestatic
, pop
, return
.
Инструкция invokestatic
вызовет метод returnStringMethod
и оставит ссылку на String
в стеке операндов. Следующая инструкция pop
удалит самую верхнюю запись стека, то есть ссылку. После этой инструкции нет ссылки на строку из текущего метода. Таким образом, он имел право на сборку мусора, если он не был строковым литералом, на который ссылались из кода. В частности, он связывается с инструкцией ldc
внутри returnStringMethod()
.
В принципе, инструкция pop
здесь не обязательна, так как инструкция return
уничтожит весь кадр стека текущего метода, включая его стек операндов.
В любом случае ответ заключается в том, что он зависит от сборщика мусора, который может позже обнаружить, что нет ссылок на объект. По крайней мере, так работает формально. В JVM также есть оптимизатор, который может определять, игнорирует ли метод объект, созданный непосредственно в вызываемом методе, и оптимизировать этот конкретный код. Тем не менее, результат больше похож на то, что вы никогда не создаете объект, а не уничтожаете его сразу после. И этот оптимизатор смотрит только на код, который оказался важным для производительности.
Другой момент заключается в том, что для вашей простой программы сборщик мусора, скорее всего, никогда не будет работать, так как он не нужен в это короткое время выполнения. Вся память кучи будет освобождена сразу после завершения работы JVM.