I tried Mo's patch on CObject.finalize() to see if any TclBlend code will leak C objects. And it does. There are a number of places in the "tcljava" code that do: TclList.index(interp,list,0).toString(); This will cause a CObject to be garbage collected without first releasing the native Tcl_Obj. Does anyone has any opinion as to how we should go about fixing these? We can make all those instance of TclList.index(...).toString() into: TclObject listElement = TclList.index(...); listElement.preserve(); listElement.toString(); listElement.release(); Or we can try to fix the CObject finalize. I propose something like this: 1. In CObject.finalize(), add any pointer to Tcl_Obj to a global Vector. Then create and queue a TclEvent. 2. Inside the TclEvent, free all Tcl_Obj on the global Vector using the Tcl interpreter thread. My problem with the above approach is that the user of TclBlend must register a Interp object to be used to perform the freeing of the Tcl_Obj. Here is some pseudo code to do the above: class CObject { protected void finalize() throws Throwable { if (objPtr != 0) { addToFreeList(objPtr); } super.finalize(); } // a vector of Tcl_Obj pointers to be free'ed private static Vector freeTclObjPtrs = new Vector(); // a lock object to synchronize access to the 'freeTclObjPtr'. private static Object freeTclObjPtrsLock = new Object(); /* * Add a pointer to the to be free'ed vector. The CObject containing * this pointer is being finalized by the GC. This method is only * called by 'CObject.finalize()'. This method is thread safe. */ private static void addToFreeList (long objPtr) { synchronized (freeTclObjPtrsLock) { freeTclObjPtrs.addElement(new Long(objPtr)); // create and queue a TclEvent, to be completed } } /* * This method makes a copy of the existing 'freeTclObjPtr' vector and * starts to free the Tcl_Obj pointers contained in the old vector. This * method should be called from inside of a TclEvent. */ static void freeTclObjs () { Vector newFreeTclObjPtrs = new Vector(); Vector oldFreeTclObjPtrs; int i; // we want to quickly grab the content of the existing // 'freeTclObjPtrs' so that we don't lock the GC thread synchronized (freeTclObjPtrsLock) { oldFreeTclObjPtrs = freeTclObjPtrs; freeTclObjPtrs = newFreeTclObjPtrs; } // now we can safely walk through the vector without any // synchronization problems. for (i = 0 ; i < oldFreeTclObjPtrs.size() ; i++) { decrRefCount(((Long) oldFreeTclObjPtrs.elementAt(i)).longValue()); } } } // end of CObject Any comments? -- Jiang Wu [EMAIL PROTECTED] ---------------------------------------------------------------- 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