Ticket UUID: | 1869989 | |||
Title: | memory leak when using expr | |||
Type: | Bug | Version: | obsolete: 8.5.0 | |
Submitter: | melbardis | Created on: | 2008-01-12 16:45:13 | |
Subsystem: | 47. Bytecode Compiler | Assigned To: | msofer | |
Priority: | 9 Immediate | Severity: | ||
Status: | Closed | Last Modified: | 2008-01-17 02:49:21 | |
Resolution: | Fixed | Closed By: | msofer | |
Closed on: | 2008-01-16 19:49:21 | |||
Description: |
using [expr ...] in a loop appears to cause a constant memory leak. it appears to be allocating stuff in TclLiterla... also fairly (very) slow operation! tcl 8.5 / windows xp here is the code i used #----------------------------- set numgen 200000 set delta 1 set start_time 1 for {set i 0} {$i < $numgen} {incr i} { set time [expr $start_time + ($delta * $i) ] } #----------------------------- memory start small, now it is about 48K and is still running! like i said slow... | |||
User Comments: |
msofer added on 2008-01-17 02:49:21:
Logged In: YES user_id=148712 Originator: NO Patch reviewed, approved, committed. dgp added on 2008-01-17 02:11:23: File Added - 262488: 1869989.patch Logged In: YES user_id=80530 Originator: NO Here's a patch that removes the unbalanced TclCreateLiteral() calls that caused the memleak. Might be interesting to see if tclbench notices anything significantly different after applying this patch. File Added: 1869989.patch dgp added on 2008-01-16 02:53:45: Logged In: YES user_id=80530 Originator: NO I would expect the same TclReleaseLiteral flaws to cause this script to leak: while 1 { proc demo {} "set ::var val[incr ::i]" demo } But that doesn't appear to be the case. dgp added on 2008-01-16 02:41:56: Logged In: YES user_id=80530 Originator: NO I was mistaken to assume that literal lifetimes were meant to be permanent. There is in fact a conflict in literal lifetime management for those literals in constant (sub-)expressions. Diagnosis of memory leak was correct after all. melbardis added on 2008-01-16 00:04:54: Logged In: YES user_id=788816 Originator: YES thanks for the explaination i guess i should of read the documentation a little better :) eric dgp added on 2008-01-16 00:00:11: Logged In: YES user_id=80530 Originator: NO 1) No limit. Yes, over time a program that creates many literals can grow in memory footprint. This is nothing new. 2) The fundamental reason is that you have failed to brace the expression. This means every evaluation of [expr] is creating an expression string, parsing that expression string (which creates literals), and only then compiling and executing the bytecode. A properly braced expression would parse and compile only one time, and let the changing contents of a variable produce changing expression results when executing the same bytecode again and again. Using [+] is more like a braced expression than an unbraced expression. For this example, they produce (nearly?) the same bytecode. Although there's no bug here, it does raise the general question of literal lifetime which might be worth looking into. melbardis added on 2008-01-15 22:51:14: Logged In: YES user_id=788816 Originator: YES it was the literal table growing that was of concern. 1) is there an upper limit to number of literals allocated? if not then this would have adverse efects on long running server apps that use this construct. 2) why the difference between [expr ..] and the alternative [+ ...] ? regards eric dgp added on 2008-01-15 13:51:05: Logged In: YES user_id=80530 Originator: NO Perhaps you are not seeing an actual leak, but just watching memory consumption grow as the accumulated parses allocate space for all the literal values they see? By the time you are done, the values "1", "2", ... "200000" will all be stored in the literal table. The same thing should happen in 8.4. dgp added on 2008-01-15 13:31:01: Logged In: YES user_id=80530 Originator: NO What is your evidence of a memory leak? Your original script runs in about 3 seconds for me on a linux system. Doesn't seem "very" slow considering you're demanding that it reparse the expression and all numbers 200000 times. Of course bracing the expression will solve that, if it is speed rather than demonstrating a leak which is at issue. [email protected] added on 2008-01-12 23:51:26: Logged In: NO i modified the test to use the opreator syntax as such: #------------------------------ namespace path {::tcl::mathop ::tcl::mathfunc} set numgen 200000 set delta 1 set start_time 1 for {set i 0} {$i < $numgen} {incr i} { #set time [expr $start_time + ($delta * $i) ] set time [+ $start_time [* $delta $i]] } #---------------------------------- almost instant! |
Attachments:
- 1869989.patch [download] added by dgp on 2008-01-17 02:11:23. [details]