[Tcl Java] Re: leaking memory
"Mo" == Mo DeJong [EMAIL PROTECTED] writes: Mo That does seem logical. It looks like the Class refs need to Mo be cleaned up. What do you think of the patch below? The patch looks good. I'll have to wait until tonight to apply it, as I can't seem to apply it to the version that I have available right now. Mo This would tend to happen if you created a lot of Tcl or Java Mo threads and loaded Tcl Blend into them. Is that what you are Mo doing? This also sounds like that mem leak problem from Mo yesterday, do this patch help? The patch is for the Mo ajuba-tclblend-contract-2000-08-01-branch branch in the CVS. Exactly. Each time someone accesses a url a new thread is spawned for the connection and tlcblend is loaded into it. In the test case that I ran, there were probably more than 20 concurrent threads with tclblend loaded into each of them. Mo That seems to happen to me too. Are you saying that you also don't see the cleanup cache method get called at the end of a thread? If not, this would indicate a problem with the tcl implementation not calling these registered cleanup procs. Mo It seems like the new cache Mo cleanup method is getting called when Tcl Blend is loaded into Mo Tcl, but I am not sure what is going on when you load Tcl Mo Blend and Tcl into a JVM. How could we test this sort of Mo thing? I'm not sure what your saying here, and it's probably because I'm used to thinking about this stuff in terms of the way it operates in conjunction with aolserver. In aolserver there is only one case: 1) Connection thread starts. 2) A new tcl interpreter is allocated to the connection thread. 3) jvm attach to the current connection thread. 4) tclblend is initialized for the current connection thread. 4) run tcl scripts with tclblend calls. 5) thread completes. 6) cleanup thread function is called. -- this doesn't happen with aolserver -Dan The TclJava mailing list is sponsored by Scriptics Corporation. To subscribe:send mail to [EMAIL PROTECTED] with the word SUBSCRIBE as the subject. To unsubscribe: send mail to [EMAIL PROTECTED] with the word UNSUBSCRIBE as the subject. To send to the list, send email to '[EMAIL PROTECTED]'. An archive is available at http://www.mail-archive.com/tcljava@scriptics.com
[Tcl Java] Re: leaking memory
"Mo" == Mo DeJong [EMAIL PROTECTED] writes: Mo There are two cleanup cases. Mo TclThreadCleanup is called when a Tcl thread (one that was not Mo started inside a JVM) is terminated. TclThreadCleanup will Mo just call DetachCurrentThread() to disconnect the Tcl thread Mo from the JVM. Mo JavaCacheCleanup should be called when a Java or Tcl thread is Mo terminated, its job is to clean up the thread local cache or Mo classes. For me these two cases seem to be one in the same. At the end of a connection thread, I need to do both JavaCacheCleanup and DetachCurrentThread. Mo I am not sure which of these you are using because the Mo description below says "Connection thread starts" and then Mo "jvm attach to the current connection thread", that would make Mo me think it is a thread created from Tcl. I think what you're saying is correct. I've always thought of it as aolserver starting a connection thread and allocating a tcl interpreter instance to run in that thread. The jvm attach is done at the start of the thread by a registered proc, and after the jvm is attached to the connection thread, tclblend is initialized. 1) Connection thread starts. 2) A new tcl interpreter is allocated to the connection thread. 3) jvm attach to the current connection thread. 4) tclblend is initialized for the current connection thread. 4) run tcl scripts with tclblend calls. 5) thread completes. 6) cleanup thread function is called. -- this doesn't happen with aolserver Mo The problem I was seeing is that JavaCacheCleanup was getting Mo called when I exited Tcl thread but when the JVM exited, I saw Mo no such callback. This might be because the finalizer was not Mo called on exit. I need to fix that problem with the Notifier Mo before I can really test this properly. I would be happy to see it called at the end of a thread, because I don't exit the jvm until aolserver is shutdown. -Dan The TclJava mailing list is sponsored by Scriptics Corporation. To subscribe:send mail to [EMAIL PROTECTED] with the word SUBSCRIBE as the subject. To unsubscribe: send mail to [EMAIL PROTECTED] with the word UNSUBSCRIBE as the subject. To send to the list, send email to '[EMAIL PROTECTED]'. An archive is available at http://www.mail-archive.com/tcljava@scriptics.com
[Tcl Java] Re: leaking memory
On Thu, 12 Oct 2000, Daniel Wickstrom wrote: "Mo" == Mo DeJong [EMAIL PROTECTED] writes: Mo There are two cleanup cases. Mo TclThreadCleanup is called when a Tcl thread (one that was not Mo started inside a JVM) is terminated. TclThreadCleanup will Mo just call DetachCurrentThread() to disconnect the Tcl thread Mo from the JVM. Mo JavaCacheCleanup should be called when a Java or Tcl thread is Mo terminated, its job is to clean up the thread local cache or Mo classes. For me these two cases seem to be one in the same. At the end of a connection thread, I need to do both JavaCacheCleanup and DetachCurrentThread. That would be the case when you created the thread in Tcl (meaning the JVM did not create the thread). Mo I am not sure which of these you are using because the Mo description below says "Connection thread starts" and then Mo "jvm attach to the current connection thread", that would make Mo me think it is a thread created from Tcl. I think what you're saying is correct. I've always thought of it as aolserver starting a connection thread and allocating a tcl interpreter instance to run in that thread. The jvm attach is done at the start of the thread by a registered proc, and after the jvm is attached to the connection thread, tclblend is initialized. What do you mean by "The jvm attach is done at the start of the thread by a registered proc"? Are you not using: (*javaVM)-AttachCurrentThread() In JavaInitEnv() to attach the Tcl thread to the JVM? This is also the place where this is called. Tcl_CreateThreadExitHandler(TclThreadCleanup, NULL); Perhaps I am just not understanding what you mean. You really should not need to do your own JVM attach, at least that is not something I had considered (ugh, we don't really need another init case). Mo DeJong Red Hat Inc The TclJava mailing list is sponsored by Scriptics Corporation. To subscribe:send mail to [EMAIL PROTECTED] with the word SUBSCRIBE as the subject. To unsubscribe: send mail to [EMAIL PROTECTED] with the word UNSUBSCRIBE as the subject. To send to the list, send email to '[EMAIL PROTECTED]'. An archive is available at http://www.mail-archive.com/tcljava@scriptics.com
[Tcl Java] Re: leaking memory
"Mo" == Mo DeJong [EMAIL PROTECTED] writes: Mo What do you mean by "The jvm attach is done at the start of Mo the thread by a registered proc"? Are you not using: Mo (*javaVM)-AttachCurrentThread() Mo In JavaInitEnv() to attach the Tcl thread to the JVM? This is Mo also the place where this is called. Mo Tcl_CreateThreadExitHandler(TclThreadCleanup, NULL); Mo Perhaps I am just not understanding what you mean. You really Mo should not need to do your own JVM attach, at least that is Mo not something I had considered (ugh, we don't really need Mo another init case). I should have elaborated. To use tclblend in aolserver, I basically had to tear apart javaCmd.c and re-implement it in the structure required by aolserver. aolserver provides functions outside of tcl to register a function at the start of a thread. I'm using this aolserver registered function to call AttachCurrentThread. I'm also calling Tcl_CreateThreadExitHandler(TclThreadCleanup, NULL) in my init routine. Other than javaCmd.c, the rest of the tclblend code is the same as what I pulled out of cvs. At some later time, when I understand everything, I'm going to try and restructure everything to use the code in javaCmd.c if possible. If not, I will have one extra 'c' file to support aolserver. -Dan The TclJava mailing list is sponsored by Scriptics Corporation. To subscribe:send mail to [EMAIL PROTECTED] with the word SUBSCRIBE as the subject. To unsubscribe: send mail to [EMAIL PROTECTED] with the word UNSUBSCRIBE as the subject. To send to the list, send email to '[EMAIL PROTECTED]'. An archive is available at http://www.mail-archive.com/tcljava@scriptics.com
[Tcl Java] Re: leaking memory
On Thu, 12 Oct 2000, Daniel Wickstrom wrote: "Mo" == Mo DeJong [EMAIL PROTECTED] writes: Mo What do you mean by "The jvm attach is done at the start of Mo the thread by a registered proc"? Are you not using: Mo (*javaVM)-AttachCurrentThread() Mo In JavaInitEnv() to attach the Tcl thread to the JVM? This is Mo also the place where this is called. Mo Tcl_CreateThreadExitHandler(TclThreadCleanup, NULL); Mo Perhaps I am just not understanding what you mean. You really Mo should not need to do your own JVM attach, at least that is Mo not something I had considered (ugh, we don't really need Mo another init case). I should have elaborated. To use tclblend in aolserver, I basically had to tear apart javaCmd.c and re-implement it in the structure required by aolserver. aolserver provides functions outside of tcl to register a function at the start of a thread. I'm using this aolserver registered function to call AttachCurrentThread. I'm also calling Tcl_CreateThreadExitHandler(TclThreadCleanup, NULL) in my init routine. Other than javaCmd.c, the rest of the tclblend code is the same as what I pulled out of cvs. At some later time, when I understand everything, I'm going to try and restructure everything to use the code in javaCmd.c if possible. If not, I will have one extra 'c' file to support aolserver. If you ask me, you time would be better spent getting the current code into "shape" so that it can be dropped into aolserver as is. The code on the branch is not really set in stone, so if you can provide a reasonable way to add your stuff with only a minimal change (like #ifdef AOLSERVER perhaps), then we could add it in without lots of duplicated functionality. Of course, it is up to you, but in the long run 1 codebase is far far better. One thing that we really should do is document the init cases, we currently have three of four ways a thread can go through the init code. It would be nice to write each one down. Mo DeJong Red Hat Inc The TclJava mailing list is sponsored by Scriptics Corporation. To subscribe:send mail to [EMAIL PROTECTED] with the word SUBSCRIBE as the subject. To unsubscribe: send mail to [EMAIL PROTECTED] with the word UNSUBSCRIBE as the subject. To send to the list, send email to '[EMAIL PROTECTED]'. An archive is available at http://www.mail-archive.com/tcljava@scriptics.com
[Tcl Java] Re: leaking memory
If you ask me, you time would be better spent getting the current code into "shape" so that it can be dropped into aolserver as is. The code on the branch is not really set in stone, so if you can provide a reasonable way to add your stuff with only a minimal change (like #ifdef AOLSERVER perhaps), then we could add it in without lots of duplicated functionality. Of course, it is up to you, but in the long run 1 codebase is far far better. I'm all for having one code base. I'll see if I can't work towards merging completely with the tclblend code. When I asked you about this originally, I was under the impression that you didn't really want me to touch any of the tclblend 'c' code. One thing that we really should do is document the init cases, we currently have three of four ways a thread can go through the init code. It would be nice to write each one down. That would be helpful. When I'm sure about the aolserver case, I'll go ahead and document it. -Dan The TclJava mailing list is sponsored by Scriptics Corporation. To subscribe:send mail to [EMAIL PROTECTED] with the word SUBSCRIBE as the subject. To unsubscribe: send mail to [EMAIL PROTECTED] with the word UNSUBSCRIBE as the subject. To send to the list, send email to '[EMAIL PROTECTED]'. An archive is available at http://www.mail-archive.com/tcljava@scriptics.com
[Tcl Java] Re: leaking memory
On Thu, 12 Oct 2000, Dan Wickstrom wrote: If you ask me, you time would be better spent getting the current code into "shape" so that it can be dropped into aolserver as is. The code on the branch is not really set in stone, so if you can provide a reasonable way to add your stuff with only a minimal change (like #ifdef AOLSERVER perhaps), then we could add it in without lots of duplicated functionality. Of course, it is up to you, but in the long run 1 codebase is far far better. I'm all for having one code base. I'll see if I can't work towards merging completely with the tclblend code. When I asked you about this originally, I was under the impression that you didn't really want me to touch any of the tclblend 'c' code. I thought you were talking about code that would only apply to aol server stuff. If it is possible to cleanly merge in your Tcl Blend init case, then I am all for that. Of course, I would need to see the patch first :) Mo DeJong Red Hat Inc The TclJava mailing list is sponsored by Scriptics Corporation. To subscribe:send mail to [EMAIL PROTECTED] with the word SUBSCRIBE as the subject. To unsubscribe: send mail to [EMAIL PROTECTED] with the word UNSUBSCRIBE as the subject. To send to the list, send email to '[EMAIL PROTECTED]'. An archive is available at http://www.mail-archive.com/tcljava@scriptics.com
[Tcl Java] Re: leaking memory
On Wed, 11 Oct 2000, Daniel Wickstrom wrote: Last weekend I ran the merged tclblend/aolserver combination using apache-bench to make concurrent accesses of multiple urls, and I noticed that the memory size was growing over time. I think this is probably due in part to the java info cache not being cleaned up. It seems that at the end of a thread, the DeleteGlobalRef should be called for each of the items in the cache. That does seem logical. It looks like the Class refs need to be cleaned up. What do you think of the patch below? This would tend to happen if you created a lot of Tcl or Java threads and loaded Tcl Blend into them. Is that what you are doing? This also sounds like that mem leak problem from yesterday, do this patch help? The patch is for the ajuba-tclblend-contract-2000-08-01-branch branch in the CVS. Another thing that I've noticed is that the TclThreadCleanup routine is not being called. I register this proc one time from the aolserver startup routine, but I'm wondering if maybe it needs to be registered at the start of each thread. -Dan That seems to happen to me too. It seems like the new cache cleanup method is getting called when Tcl Blend is loaded into Tcl, but I am not sure what is going on when you load Tcl Blend and Tcl into a JVM. How could we test this sort of thing? Here is my proposed patch to cleanup the Class refs. I am also going to attach it to this file because it is going to get hosed in mail. Mo DeJong Red Hat Inc Index: tcljava/src/native/javaCmd.c === RCS file: /home/cvs/external/tcljava/src/native/javaCmd.c,v retrieving revision 1.9.2.7 diff -u -r1.9.2.7 javaCmd.c --- javaCmd.c 2000/08/27 08:07:40 1.9.2.7 +++ javaCmd.c 2000/10/12 06:00:15 @@ -104,6 +104,7 @@ static int AddToFieldCache(JNIEnv *env, Tcl_Interp *interp, jfieldID *addr, char *name, jclass *class, char *sig); static voidTclThreadCleanup(ClientData clientData); +static voidJavaCacheCleanup(ClientData clientData); /* *-- @@ -206,7 +207,7 @@ #ifdef TCLBLEND_DEBUG fprintf(stderr, "TCLBLEND_DEBUG: Tclblend_Init finished\n"); -fprintf(stderr, "TCLBLEND_DEBUG: JavaInitBlend() returned "); +fprintf(stderr, "TCLBLEND_DEBUG: JavaInitBlend returned "); if (result == TCL_ERROR) { fprintf(stderr, "TCL_ERROR"); } else if (result == TCL_OK) { @@ -393,6 +394,8 @@ * From this point on, deal with the case where Tcl Blend is loaded from Tcl. * Check to see if the current process already has a Java VM. If so, attach * the current thread to it, otherwise create a new JVM (automatic thread attach). + * In the case where Tcl Blend is loaded into Java, the call to + * JNI_GetCreatedJavaVMs will fill in the javaVM pointer with the JVM pointer. */ if (JNI_GetCreatedJavaVMs(javaVM, 1, nVMs) 0) { @@ -558,7 +561,7 @@ goto error; } -} else { +} else { /* (nVMs == 0) */ #ifdef TCLBLEND_DEBUG fprintf(stderr, "TCLBLEND_DEBUG: JVM in process, attaching\n"); @@ -734,20 +737,66 @@ static void TclThreadCleanup(ClientData clientData) { -JNIEnv* env; -ThreadSpecificData *tsdPtr = TCL_TSD_INIT(dataKey); - #ifdef TCLBLEND_DEBUG fprintf(stderr, "TCLBLEND_DEBUG: called TclThreadCleanup\n"); #endif /* TCLBLEND_DEBUG */ -env = tsdPtr-currentEnv; (*javaVM)-DetachCurrentThread(javaVM); } /* *-- * + * JavaCacheCleanup -- + * + * This method will be called when a Tcl or Java thread is finished. + * It needs to remove any global cache references so that the + * classes and methods can be cleaned up by the JVM. + * + * Results: + * None. + * + * Side effects: + * None. + * + *-- + */ +static void +JavaCacheCleanup(ClientData clientData) +{ +JNIEnv* env = JavaGetEnv(); +JavaInfo* jcache = JavaGetCache(); + +/* FIXME: need to add code to check for case where TclThreadCleanup is called first */ + +#ifdef TCLBLEND_DEBUG +fprintf(stderr, "TCLBLEND_DEBUG: called JavaCacheCleanup\n"); +#endif /* TCLBLEND_DEBUG */ + +/* We need to delete any global refs to Java classes */ + +(*env)-DeleteGlobalRef(env, jcache-Object); +(*env)-DeleteGlobalRef(env, jcache-Interp); +(*env)-DeleteGlobalRef(env, jcache-Command); +(*env)-DeleteGlobalRef(env, jcache-TclObject); +(*env)-DeleteGlobalRef(env, jcache-TclException); +(*env)-DeleteGlobalRef(env, jcache-CommandWithDispose); +(*env)-DeleteGlobalRef(env, jcache-CObject); +(*env)-DeleteGlobalRef(env, jcache-Extension); +(*env)-DeleteGlobalRef(env, jcache-VarTrace); +(*env)-DeleteGlobalRef(env, jcache-Void); +