🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Article View: cn.bbs.comp.lang.java
Article #24486

chat room ����֮��

#24486
From: diff.bbs
Date: Fri, 09 Jan 1998 00:00
235 lines
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>

--
 ��Դ: ����������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-mail

Show 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,