[android-beginners] Re: Garbage Collection of Threads

2009-07-06 Thread fadden

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

2009-07-03 Thread Drifter

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

2009-06-24 Thread fadden

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

2009-06-24 Thread fadden

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

2009-06-23 Thread Drifter

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

2009-06-23 Thread fadden

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
-~--~~~~--~~--~--~---