当分配新的空白字典时,tcl是否释放现有dict变量的内存?

时间:2016-11-11 06:04:17

标签: dictionary tcl

我的tcl应用程序使用字典来存储大型数据库,并且必须确保内存不会显着爆炸。我正在寻找一种简单的方法来释放整个字典的记忆。

在下面的代码序列中,我将一个空白字典重新分配给一个已经有一个与它相关的大尺寸字典的变量。我可以看到带有变量的新字典的内容是空的,但它是否也会释放内存?换句话说,这相当于为键值对执行未设置的语句吗?

set db [dict create]
dict set db key1 value1
dict set db key2 value2

# Will this next step recover memory of all previous key-value assignments?
set db [dict create]

1 个答案:

答案 0 :(得分:1)

背景信息:Tcl的语言模型是每个值都是一个字符串。严格地说,在实现级别,每个值都正式为字符串的子类型,并且值通过引用传递,引用是不可变的(因此在写入时会被复制)如果它们是共享的。非共享值是可写的,尽管Tcl在内部对非常严格解释,并且细节通常完全隐藏在脚本中;在你处理优化性能之前,你不应该想到这些东西,即便那么多。

所以......

后果:当对该词典的最后一次引用消失时,将自动回收用于实现字典的内存。这与列表或大字符串中的相同。 (好吧,小字符串和数字,但它们通常不是什么大不了的。)

所以,如果我这样做:

set db [dict create big "bigger" biggest "even more"]
set db2 $db
unset db

然后仍然分配内存,因为db2变量持有引用。用unset dbset db {}替换set db [dict create]将产生几乎相同的效果;原来的字典还在闲逛。但是,一旦 last 对它的引用消失了(甚至可能来自另一个字典或列表中),那么内存就会被整理掉。

所以是的,在您的确切示例中,内存被释放。我们可以通过运行这个循环证明这一点:

while true {
    set db [dict create]
    dict set db key1 value1
    dict set db key2 value2
    set db [dict create]
}

并且看到OS认为即使CPU使用率(接近)CPU核心的100%,该进程的内存使用量也是静态的。如果它泄露了内存,你看到它! (你可以通过在该循环中添加lappend save $db来确认这是一个合理的测试,并且看到内存使用量快速增长。一旦你看到它确实是一个内存,你会想要很快地杀死它最糟糕的猪...)