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

Dictionary 分配新的空白dict时,tcl是否释放现有dict变量的内存?,dictionary,tcl,Dictionary,Tcl,我的tcl应用程序使用字典来存储大型数据库,并且必须确保内存不会显著膨胀。我正在寻找一种简单的方法来释放整个字典的内存 在下面的代码序列中,我将一个空白dict重新分配给一个变量,该变量已经有一个大的dict与之关联。我可以看到带有变量的新dict的内容是空的,但它也会释放内存吗?换句话说,这是否等同于对键值对执行unset语句 set db [dict create] dict set db key1 value1 dict set db key2 value2 # Will this ne

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

在下面的代码序列中,我将一个空白dict重新分配给一个变量,该变量已经有一个大的dict与之关联。我可以看到带有变量的新dict的内容是空的,但它也会释放内存吗?换句话说,这是否等同于对键值对执行unset语句

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]

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

所以

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

因此,如果我这样做:

set db [dict create big "bigger" biggest "even more"]
set db2 $db
unset db
然后,当
db2
变量保存引用时,仍然会分配内存。将
unset db
替换为
set db{}
set db[dict create]
将产生几乎相同的效果;那本原版词典仍在流传。然而,一旦对它的最后一次引用消失(甚至可能是从另一个字典或列表中),内存就会被整理

是的,在你的例子中,内存被释放了。我们可以通过运行以下循环来证明这一点:

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

看到操作系统认为进程的内存使用是静态的,即使CPU使用率(接近)CPU核心的100%。如果它泄露了内存,你会看到的!(您可以通过在该循环中添加
lappend save$db
并查看内存使用量的快速增长来确认这是一个合理的测试。一旦您看到该进程确实是一个最糟糕的内存占用程序,您就会想相当快地终止该进程…

好了,Tcl不会将内存返回到操作系统,但是用于字典的内存将被重用。在这种情况下,上面的代码会告诉Tcl之前占用的内存对于其他变量来说是空闲的吗?换句话说,Tcl不会在操作系统已有可用内存的情况下从操作系统中获取更多内存。@MadhurKashyap您可以通过循环运行代码并查看操作系统内存监视器来证明这一点。总体内存使用将是恒定的,因此从操作系统的角度来看,显然没有额外的内存使用,因此必须重用内存。Tcl通常不会将内存返回操作系统,但在实践中这通常不是什么大问题;大多数表现良好的进程所需的最大内存量都是有限的,如果需要,操作系统可以使用分页进行管理。Tcl使用malloc()/free()进行对象分配。这取决于操作系统是否“看到”释放的内存。如果需要深入分析Tcl内存使用情况,请使用启用“memory”命令的Tcl_MEM_调试集编译Tcl库(请参阅man 3tcl memory)。