Ticket UUID: | 2874678 | |||
Title: | dict incr leaks | |||
Type: | Bug | Version: | obsolete: 8.5.7 | |
Submitter: | wastl-nagel | Created on: | 2009-10-08 12:35:15 | |
Subsystem: | 15. Dict Object | Assigned To: | dkf | |
Priority: | 9 Immediate | Severity: | ||
Status: | Closed | Last Modified: | 2009-10-08 21:44:12 | |
Resolution: | Fixed | Closed By: | dkf | |
Closed on: | 2009-10-08 14:44:12 | |||
Description: |
If a dict is created and filled via "dict incr" with a bigger set of keys it seems to leak. If the dict is destroyed (unset or overwritten) a lot of memory still keeps allocated. The following code consumes approx. 500MB memory on my machine (Linux, 64-bit): set chars {a b c d e f g h i j k l m n o p q r s t u v w x y z A B C D E F G H I J K L M N O P Q R S T U V W X Y Z 0 1 2 3 4 5 6 7 8 9} for {set i 0} {$i < 1000} {incr i} { append prefix [lindex $chars [expr int([tcl::mathfunc::rand]*62)]] set dictionary [dict create] foreach char $chars { foreach c $chars { dict incr dictionary $prefix$char$c $i } } } I've tested Tcl 8.5.2 (OpenSuSE 11.0, x86_64), 8.5.7, 8.6b1 (both built from source), all three leak, cf. attached valgrind log files for same code but only 100 cycles. For 8.5.2 TclBN_mp_init_size according to valgrind seems to be reason. % uname -mrvs Linux 2.6.25.20-0.5-default #1 SMP 2009-08-14 01:48:11 +0200 x86_64 | |||
User Comments: |
dkf added on 2009-10-08 21:44:12:
allow_comments - 1 dkf added on 2009-10-08 21:44:11: Fixed in HEAD and 8.5 (the patch was slightly wrong, but helped narrow down what needed to be done a lot; thanks!) dkf added on 2009-10-08 21:24:57: The following test seems to be exact: test dict-19.3 {dict: testing for leaks - Bug 2874678} -setup { proc memtest script { set end [lindex [split [memory info] \n] 3 3] for {set i 0} {$i < 5} {incr i} { uplevel 1 $script set tmp $end set end [lindex [split [memory info] \n] 3 3] } expr {$end - $tmp} } } -constraints memory -body { set d aDictVar; # Force interpreted [dict incr] memtest { dict incr $d aKey 0 unset $d } } -cleanup { unset d rename memtest {} } -result 0 dkf added on 2009-10-08 21:22:24: And requires an explicit increment to do so. dkf added on 2009-10-08 21:21:09: Leaks 8 words per *interpreted* [dict incr] that creates a dictionary entry. wastl-nagel added on 2009-10-08 20:26:03: May the patch below fix the problem? --- ./generic/tclDictObj.c~ 2009-01-06 17:07:17.000000000 +0100 +++ ./generic/tclDictObj.c 2009-10-08 15:00:29.000000000 +0200 @@ -2148,6 +2148,7 @@ mp_int increment; code = Tcl_GetBignumFromObj(interp, objv[3], &increment); + mp_clear(&increment); if (code != TCL_OK) { Tcl_AddErrorInfo(interp, "\n (reading increment)"); } else { wastl-nagel added on 2009-10-08 19:35:20: File Added - 345735: valgrind_tcl_dict.zip |
Attachments:
- valgrind_tcl_dict.zip [download] added by wastl-nagel on 2009-10-08 19:35:19. [details]