Article View: cn.bbs.comp.lang.java
Article #24486chat room ����֮��
From: diff.bbs
Date: Fri, 09 Jan 1998 00:00
Date: Fri, 09 Jan 1998 00:00
235 lines
8796 bytes
8796 bytes
<pre>
��������̫æ�ˣ������ûϸ��������д����ŵļһ�Ƚ�������
����Ķ��������ڱȽ�ʵ�õ����ࡣ
this is in private email since it's very long. feel free
to quote any of it in a reply to the list, if you want.
i've posted the text to my web page:
http://cdo.weblinq.com/~tiger/code/java/java-yorku/Threads1.html
i suggest that if you want to quote any of it, you quote
only small parts and then point the people on the list to
the web page. that way, we can save a little bandwidth.
[On 08:27 PM 1/7/98 +0800, Gao Lei wrote]
> MyThread thread1 = new MyThread();
> thread1.start();
> ...
>
> public class MyThread extends Thread
> {
> public void run()
> {
> while(true) {}
> }
> }
let's say that nowhere else in your own code do you hold a
reference to thread1. that is, you set your last reference
to it to null or to some other (newly created, probably)
MyThread.
>when I use thread1.stop();
>I dont thinks the memory alloced for the thread OBJECT is
>reclaim.
you can get a general idea of when the thread object is
GCed by giving it a protected void finalize() method. this
method would print to the screen, or to a log file, or to
whatever you want. when it prints (or when it sets a
boolean somewhere), you know that the thread has died. see
attached very simple example (Threads.java).
>Only when your explicitly assign the thread1 = null, the
>memory is rellocated by GC.
not really. even if *you* no longer have a reference to the
thread, if the thread is still running then the JVM still
holds a reference to it. so it's not the case that just
because you null your last reference to it, that there are
no longer *ANY* references to it.
when the thread stops running (because run() exits/returns,
or because you throw a Throwable at it, or stop() it), *then*
the JVM loses its reference to it and it becomes a candidate
for GC.
>Only at that time, I think the thread1's memory is reclaimed.
even then, the memory that is reachable only from the thread
is not going to be reclaimed. you have to wait until the next
time the JVM does a GC. or you can request GC by calling
System.gc();
>Am I right?
1. make sure you don't have a reference to the thread, or
to any other object that has a reference to the thread.
2. make sure that the thread exits its run method. if
it hasn't exited yet, it won't be GCed.
3. make sure that the JVM actually does a GC. note, just
calling System.gc(), even many times, won't ensure
this. use some object's finalize() method to set a
flag whenever GC occurs or something.
>In JDK1.2, there's no stop() method anymore, and that means
>even a thread is in it's running state, you can kill it via
>assign it a null reference.
actually, no. as i said, the JVM still holds a reference to
the running thread.
stop() is removed in 1.2 because it can cause certain types
of deadlock. e.g., what happens if a thread holds a lock
(logical, monitor, whatever) on some resource, and you kill
the thread with stop()? if the lock isn't automatically
released by the exception handler (very common if the lock
is a boolean flag somewhere, or a counter, or even an open
file used as a monitor or something), then the resource will
remain locked and more than likely the process will stop
working since there's no way to detect or fix the deadlock.
if you want to stop a thread without using the stop() method,
you'll have to figure out another way (e.g. set a boolean that
the thread checks every once in a while, call
Thread.interrupt() and have the thread check every once in a
while if it's been interrupted, throw a Throwable at the
thread, and then make sure that the thread releases all
locks in the exception handler).
>BTW: How to monitering the memory variation during java
>programming running?
-verbosegc is one (i agree, it's hard to read, that's why i
never use this :), there's also java.lang.Runtime().freeMemory()
and totalMemory(). if you use the technique of monitoring when
GC occurs, you can call Runtime().freeMemory() right after a
GC (well, approximately right after :) and get a general idea
of how much things changed.
i don't do that either though. usually, i just look at the win95 System Monitor. look at the # of Kernel Threads, Allocated Memory and maybe Swapfile in use.
i only look at the detailed stuff when i'm desperate. usually
the high level information that the System Monitor provides
is good enough. in Linux, "top" will give you this
information (well, mostly. there are no kernel threads in
Linux java yet). other OSes should have similar features.
>Can any prof file do some help?
the prof file gives you which methods were called, how many
times and how much time was spent in each. for methods with
low hit counts, take the "time spent" number with a grain of
salt. the prof file usually won't help you very much with
memory problems.
tiger
/*
Threads.java
simple demo of how to detect when objects (including threads) are
finalized. this gives a rough indication of when the objects
(and probably all other objects that are reachable only from
them) are GCed.
we create a few threads pretty quickly (10 threads within 2 seconds,
with artificial sleeps between thread creation).
each of these threads just sleeps for 10 seconds.
on win95, the threads are not GCed right after they stop running.
has to do with the low priority of the GC thread maybe, or the fact
that we're not exercising memory, so the system doesn't GC since
there's no indication that more memory is needed.
we wait just long enough to see if the threads will be GCed by the
JVM just because they're finished and are no longer referenced
anywhere else. they're not, on my machine.
we then request GC several times.
GC finally occurs and the finalize() method is called (showing us
that the threads have been GCed).
the program sleeps some more, to demonstrate that the GC didn't
occur just because the program was exiting (although we didn't
call runFinalizersOnExit()) but rather because we requested
GC.
*/
import java.io.*;
public class Threads extends Thread
{
private static int nThreads=0;
private int threadNo=-1;
public Threads()
{
nThreads++;
threadNo=nThreads;
}
public void run()
{
System.out.println("Threads # "+threadNo+" starting. Should end in 10 seconds");
try
{
Thread.sleep(10*1000);
}
catch(InterruptedException ix){}
// exiting run. wait for it to finalize
}
protected void finalize()
{
System.out.println("Thread # "+threadNo+"being finalized");
notifyAll();
}
public static void main(String args[])
{
for(int ctr=0;ctr<5;ctr++)
{
Threads t=new Threads();
t.start();
try
{
Thread.sleep(200);
}
catch(InterruptedException ix){}
}
try
{
Thread.sleep(15*1000);
}catch(InterruptedException ix){}
System.out.println("Requesting GC now");
for(int ctr=0;ctr<5;ctr++)
System.gc();
try
{
Thread.sleep(60*1000);
}
catch(InterruptedException ix){}
}
}
</pre>
--
[1;36m ��Դ: ����������BBSվ��bbs.nease.net�E[FROM: www-post@bbs.nease.n]
Technical Details
Message-ID:
<3MSN5B$7yX@bbs.nease.net>Path:
arc1-ca.pugleaf.net!unknown!not-for-mailShow Full Headers
Complete Article Headers
X-Google-Language: Chinese,GB X-Google-Thread: f6cb0,bde99c074028fedf,start X-Google-Attributes: gidf6cb0,public From: diff.bbs@bbs.nease.net () Subject: chat room ����֮�� Date: 1998/01/09 Message-ID: <3MSN5B$7yX@bbs.nease.net> X-Deja-AN: 314281562 X-Filename: Java/M.884346875.A Organization: gzdcb Newsgroups: cn.bbs.comp.lang.java,