On Jun 23, 8:30 pm, Drifter <daveh...@yahoo.co.uk> wrote:
> Unfortunately I've altered the code to actually start the TestThread
> and it still doesn't hit the breakpoint. Is there any way of
> implementing this without leaking TestThreads?

I tried your example as a simple class invoked from the shell.  It ran
the finalizer just fine.

Put this in Foo.java:

public class Foo {
    public static void main(String[] args) {
        TestThread t = new TestThread();

        t.start();
        try {
            t.join();
        } catch (InterruptedException ie) {}

        t = null;
        System.gc();

        /*
        try {
            Thread.sleep(1000);
        } catch (InterruptedException ie) {}
        */

        System.out.println("exiting " + t);
    }
}

class TestThread extends Thread {
    @Override
    public void run()  {
        System.out.println("Running...");
    }

    protected void finalize() throws Throwable {
        System.out.println("finalizing TestThread");
        super.finalize();
    }
}

Then:

% javac -g Foo.java
% dx --dex --output=foo.jar Foo.class TestThread.class
% adb push foo.jar /sdcard
% adb shell dalvikvm -cp /sdcard/foo.jar Foo
  Running...
  finalizing TestThread
  exiting null

The sleep call may be needed to prevent the VM from exiting before the
finalizer thread has a chance to run.  The VM is not guaranteed to run
finalizers immediately, and may never invoke them at all if the VM
exits quickly.  In practice there seems to be enough of a lag from
handling the concatenating println call.

Incidentally, the "+ t" is on there to ensure that the "t = null"
actually happens.  If you use "javac Foo.java" instead of "javac -g
Foo.java", dx doesn't try to preserve debugging information.  Since it
doesn't think anybody will see the state of "t" after the null
assignment, it removes the assignment, and "t" still holds a valid
reference.

If we had live-precise GC this would be fine, since the GC would
ignore the never-used-again local.  We don't have live-precise GC,
which makes things a little weird if you're compiling with debugging
info disabled.  (I assume you have debugging enabled since you're
talking about setting breakpoints.)

Pedantic note: neither System.gc() nor System.runFinalization() are
guaranteed to do anything at all.  System.gc() may discard some but
not all objects, or it may just return immediately.
System.runFinalization() may wake up the finalization thread and
return immediately.  I happen to know that, in the current
implementation, System.gc() collects everything it can and
System.runFinalization() doesn't return until the finalizer queue is
empty, but you really don't want to depend on that in shipping code.

--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google
Groups "Android Beginners" group.
To post to this group, send email to android-beginners@googlegroups.com
To unsubscribe from this group, send email to
android-beginners-unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/android-beginners?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to