Hey all,
I think that I've identified a memory leak, but I'm not sure how to fix
it. A little background:
The first thing I did was enable memory tracing in tcl by compiling it
with TCL_MEM_DEBUG enabled. I then ran a script that I knew was giving
memory leaks and observed the output. Here is the script:
proc tst_blend { } {
ns_log Debug "inside tst_blend"
set tsts [java::new tcl.lang.NsjavaTests]
set fields [java::new {String[]} {2}]
$fields set 0 "last_name"
$fields set 1 "email"
set users [$tsts list_users $fields]
set els [$users elements]
while { [$els hasMoreElements] } {
set u [$els nextElement]
set u [java::cast java.util.Hashtable $u]
set kys [$u keys]
while { [$kys hasMoreElements] } {
set ky [$kys nextElement]
set value [$u get $ky]
append page "<tr><td>[$ky toString]</td><td>[$value
toString]</td></tr>"
}
}
ns_log Debug "exiting tst_blend"
}
proc ab2 { conn why } {
ReturnHeaders
ns_write "[ad_header {nsjava test}]"
ns_log Debug "entering tst_blend"
ns_log Debug "before memory info = [memory info]"
memory trace on
tst_blend
memory trace off
ns_log Debug "after memory info = [memory info]"
ns_log Debug "outside tst_blend"
ns_write "[ad_footer]"
}
ns_register_proc GET ab2 ab2
The memory trace on and memory trace off commands turn on the tracing of
all mallocs and frees within tcl. I then collected the output and ran a
script to match up the mallocs and frees. Here is a sample of the
output (I've added line numbers so I could build a cross-reference for
the allocs and frees):
1683 ckalloc 8ce23d8 24 ./../generic/tclResult.c
834: freed at 1699
1684 ckalloc 8ce1f70 24 javaList.c
402
1685 ckalloc 8ce2560 4 nsjava.c
1511
1686 ckalloc 8ce2598 4 ./../generic/tclListObj.c
922: freed at 1694
1687 ckalloc 8ce25d0 4 ./../generic/tclListObj.c
948: freed at 1692
1688 ckalloc 8ce1510 24 ./../generic/tclListObj.c
956: freed at 1693
1689 ckalloc 8ce2608 12 ./../generic/tclListObj.c
963: freed at 1695
1690 ckalloc 8ce2648 6 javaObj.c
341: freed at 1691
1691 ckfree 8ce2648 6 javaObj.c
369: alloc'd at 1690
1692 ckfree 8ce25d0 4 ./../generic/tclObj.c
802: alloc'd at 1687
1693 ckfree 8ce1510 24 ./../generic/tclObj.c
592: alloc'd at 1688
1694 ckfree 8ce2598 4 ./../generic/tclListObj.c
795: alloc'd at 1686
1695 ckfree 8ce2608 12 ./../generic/tclListObj.c
796: alloc'd at 1689
1696 ckalloc 8ce25a8 25 ./../generic/tclHash.c
513: freed at 1899
1697 ckalloc 8ce25f8 52 ./../generic/tclBasic.c
1649: freed at 1900
1698 ckalloc 8ce1510 24 javaObj.c
279: freed at 1902
1699 ckfree 8ce23d8 24 ./../generic/tclResult.c
355: alloc'd at 1683
1700 ckfree 8ce1968 9 ./../generic/tclVar.c
1508: alloc'd at 1616
1701 ckfree 8ce2140 25 ./../generic/tclHash.c
151: alloc'd at 1590
1702 ckfree 8ce2190 52 ./../generic/tclBasic.c
2413: alloc'd at 1591
1703 ckfree 8ce2280 24 ./../generic/tclExecute.c
4924: alloc'd at 1617
1704 ckfree 8ce0ba0 24 ./../generic/tclVar.c
1508: alloc'd at 1592
1705 ckalloc 8ce23d8 9 nsjava.c
1511: freed at 1876
1706 ckalloc 8ce1968 24 ./../generic/tclExecute.c
5030: freed at 1879
1707 ckalloc 8ce2280 24 ./../generic/tclResult.c
834: freed at 1721
1708 ckalloc 8ce0ba0 24 javaList.c
402
1709 ckalloc 8ce2660 9 nsjava.c
1511
1710 ckalloc 8ce26a0 4 ./../generic/tclListObj.c
922: freed at 1718
1711 ckalloc 8ce26d8 9 ./../generic/tclListObj.c
948: freed at 1716
1712 ckalloc 8ce2718 24 ./../generic/tclListObj.c
956: freed at 1717
1713 ckalloc 8ce2760 12 ./../generic/tclListObj.c
963: freed at 1719
1714 ckalloc 8ce27a0 16 javaObj.c
341: freed at 1715
1715 ckfree 8ce27a0 16 javaObj.c
369: alloc'd at 1714
1716 ckfree 8ce26d8 9 ./../generic/tclObj.c
802: alloc'd at 1711
1717 ckfree 8ce2718 24 ./../generic/tclObj.c
592: alloc'd at 1712
1718 ckfree 8ce26a0 4 ./../generic/tclListObj.c
795: alloc'd at 1710
1719 ckfree 8ce2760 12 ./../generic/tclListObj.c
796: alloc'd at 1713
1720 ckalloc 8ce26a0 24 javaObj.c
279: freed at 1744
1721 ckfree 8ce2280 24 ./../generic/tclResult.c
355: alloc'd at 1707
1722 ckalloc 8ce2280 9 nsjava.c
1511: freed at 1898
1723 ckalloc 8ce26e8 24 ./../generic/tclExecute.c
5030: freed at 1901
1724 ckalloc 8ce2730 24 ./../generic/tclResult.c
834: freed at 1738
1725 ckalloc 8ce2778 24 javaList.c
402
1726 ckalloc 8ce27c0 9 nsjava.c
1511
1727 ckalloc 8ce2800 4 ./../generic/tclListObj.c
922: freed at 1735
The complete trace is quite long, and I have only shown a small portion
of it here, but one thing is consistent, I never see the memory
allocated at javaList.c line 402 and nsjava.c line 1511 get freed up.
The function in javaList is Java_tcl_lang_TclList_splitList and the 24
byte allocation corresponds to a new Tcl_Obj. The function called from
nsjava.c line 1511 is JavaGetString (nsjava is my hacked up version of
javaCmd.c which supports the aolserver interface) and the 9 bytes only
correspond to an allocation for a char array. It's also important to
note that I'm using the reference counting changes suggested by Jiang
Wu in a patch that he posted on the list here a while back.
It appears that the splitList method is only called from within the
setListFromAny method The setListFromAny method is then used in most
of the TclList methods. It's not clear to me why the TclList object and
the underlying Tcl_Obj wouldn't get cleaned up.
-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