[android-beginners] Re: Garbage Collection of Threads
On Jul 3, 4:50 pm, Drifter wrote: > I've finally figured out the discrepancy. Using the following code, I > ran it through the debugger (in Eclipse, WinXP, emulator) and then ran > it just through the emulator - I get different results. The debugger > shows "TestThread Running" while the non-debugger version shows > "TestThread FinaIizing". I believe the debugger holds a reference to > the TestThread which prevents it from getting garbage collected. Yes, I should've spotted that earlier. The debugger queries all threads, and references to the Thread objects get passed around. The debugger support in Dalvik is somewhat simple-minded, and takes the approach that anything the debugger might care about cannot be discarded. (This isn't necessary, but it does make life a lot simpler.) So yes, if you have a debugger attached you're not going to see Thread objects get collected. (You also won't see most Exception objects get cleaned up, which is rather more of a problem.) See "Known Issues and Limitations" in dalvik/docs/debugger.html, or http://android.git.kernel.org/?p=platform/dalvik.git;a=blob_plain;f=docs/debugger.html;hb=HEAD . I'll add a note about Thread objects. --~--~-~--~~~---~--~~ 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 -~--~~~~--~~--~--~---
[android-beginners] Re: Garbage Collection of Threads
Thanks for all your help. I've finally figured out the discrepancy. Using the following code, I ran it through the debugger (in Eclipse, WinXP, emulator) and then ran it just through the emulator - I get different results. The debugger shows "TestThread Running" while the non-debugger version shows "TestThread FinaIizing". I believe the debugger holds a reference to the TestThread which prevents it from getting garbage collected. Of course, as you said this is all technically valid since System.gc() is not guaranteed to do anything, but it's nice to know it won't have any memory leaks on the final version. package com.example.helloandroid; import android.app.Activity; import android.os.Bundle; import android.widget.TextView; public class HelloAndroid extends Activity { /** Called when the activity is first created. */ TextView mTV; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); mTV = new TextView(this); mTV.setText("Hello, Android"); setContentView(mTV); TestThread t = new TestThread(); t.start(); try { t.join(); } catch (InterruptedException e) { e.printStackTrace(); } t = null; System.gc(); } protected void finalize() throws Throwable { super.finalize(); } class TestThread extends Thread { @Override public void run() { mTV.setText("TestThread Running"); } protected void finalize() throws Throwable { mTV.setText("TestThread Finalizing"); super.finalize(); } } } --~--~-~--~~~---~--~~ 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 -~--~~~~--~~--~--~---
[android-beginners] Re: Garbage Collection of Threads
Somebody pointed me at this: http://bugs.sun.com/view_bug.do?bug_id=4410846 Apparently we're not the first. :-) --~--~-~--~~~---~--~~ 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 -~--~~~~--~~--~--~---
[android-beginners] Re: Garbage Collection of Threads
On Jun 23, 8:30 pm, Drifter 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 -~--~~~~--~~--~--~---
[android-beginners] Re: Garbage Collection of Threads
Thanks so much for replying. 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? package com.example.helloandroid; import android.app.Activity; import android.os.Bundle; import android.widget.TextView; public class HelloAndroid extends Activity { /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); TextView tv = new TextView(this); tv.setText("Hello, Android"); setContentView(tv); TestThread t = new TestThread(); t.start(); try { t.join(); } catch (InterruptedException e) { e.printStackTrace(); } t = null; System.gc(); } class TestThread extends Thread { @Override public void run() { } protected void finalize() throws Throwable { super.finalize(); } } } On Jun 23, 2:55 pm, fadden wrote: > On Jun 22, 11:19 pm, Drifter wrote: > > > I don't seem to able to get a Thread to be garbage collected. Below is > > the source code (modified from HelloAndroid). I put a break point in > > the finalize function and it never seems to get called. If I remove > > "extends Thread" from the TestThread definition then the finalize > > function gets called as expected. What's going on? > > What's going on is the implementation of java.lang.Thread is adding > the object to a ThreadGroup when the object is first created. > However, the ThreadGroup.remove() call is only made from inside the VM > when a thread exits. Since the thread is never started, it's never > removed from the ThreadGroup, and you're leaking TestThread objects. > > This would be a bug. --~--~-~--~~~---~--~~ 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 -~--~~~~--~~--~--~---
[android-beginners] Re: Garbage Collection of Threads
On Jun 22, 11:19 pm, Drifter wrote: > I don't seem to able to get a Thread to be garbage collected. Below is > the source code (modified from HelloAndroid). I put a break point in > the finalize function and it never seems to get called. If I remove > "extends Thread" from the TestThread definition then the finalize > function gets called as expected. What's going on? What's going on is the implementation of java.lang.Thread is adding the object to a ThreadGroup when the object is first created. However, the ThreadGroup.remove() call is only made from inside the VM when a thread exits. Since the thread is never started, it's never removed from the ThreadGroup, and you're leaking TestThread objects. This would be a bug. --~--~-~--~~~---~--~~ 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 -~--~~~~--~~--~--~---