Estaba leyendo "CLR mediante C#" y parece que en este ejemplo, el objeto que se asignó inicialmente a 'obj' será elegible para Garbage Collection después de que se ejecute la línea 1, no después línea 2.Vida útil de los objetos en Java vs .Net
void Foo()
{
Object obj = new Object();
obj = null;
}
Eso es porque la vida útil variable local no se define por el alcance en el que se define, sino por la última vez que se leyó.
Entonces mi pregunta es: ¿qué hay de Java? He escrito este programa para verificar tal comportamiento, y parece que el objeto se mantiene vivo. No creo que sea posible para la JVM limitar la vida útil de la variable mientras se interpreta bytecode, así que traté de ejecutar el programa con 'java -Xcomp' para forzar la compilación de métodos, pero 'finalizar' no se llama de todos modos. Parece que eso no es cierto para Java, pero espero que pueda obtener una respuesta más precisa aquí. Además, ¿qué pasa con la máquina virtual Dalvik de Android?
class TestProgram {
public static void main(String[] args) {
TestProgram ref = new TestProgram();
System.gc();
}
@Override
protected void finalize() {
System.out.println("finalized");
}
}
Agregado: Jeffrey Richter da ejemplo de código en "CLR a través de C#", algo como esto:
public static void Main (string[] args)
{
var timer = new Timer(TimerCallback, null, 0, 1000); // call every second
Console.ReadLine();
}
public static void TimerCallback(Object o)
{
Console.WriteLine("Callback!");
GC.Collect();
}
TimerCallback llama sólo una vez en MS .Net si los proyectos objetivo es 'Release' (temporizador destruido después de GC.Collect() llamada), y llamado cada segundo si el objetivo es 'Debug' (las variables de la vida útil aumentan porque el programador puede intentar acceder al objeto con el depurador). Pero en la devolución de llamada Mono se llama cada segundo, sin importar cómo lo compile. Parece que la implementación de Mono "Timer" almacena referencias a la instancia en algún lugar del grupo de subprocesos. La implementación de MS no hace esto.
No he podido encontrar esto antes en las especificaciones de Java. Tenga en cuenta que .NET puede ser aún más loco de lo que cabría esperar: es posible que se recopile una instancia * mientras se ejecuta un método de instancia * si el CLR sabe que no se hará referencia a más variables de instancia. –