KDB/Q内存消耗

KDB/Q内存消耗,kdb,Kdb,我有一个KDB/Q数据库,每天约有200万条记录,消耗约2G内存。在一天结束时,它运行一些报告工作,在表之间进行连接,并将结果输出到磁盘上的文件中。在计算过程中,内存使用量增加到约15G。我的问题是,一旦这个操作完成,内存永远不会释放回来,直到数据库重新启动,它会消耗掉所有的15G内存 我想告诉KDB从内存中卸载一些表(但不要删除它们),但我不想重新启动DB,因为其他一些应用程序仍在连接它 有没有办法告诉KDB从内存中卸载某些内容 编辑: 如果有人觉得有趣,我建议大家看看KDB 2.5+,看起来

我有一个KDB/Q数据库,每天约有200万条记录,消耗约2G内存。在一天结束时,它运行一些报告工作,在表之间进行连接,并将结果输出到磁盘上的文件中。在计算过程中,内存使用量增加到约15G。我的问题是,一旦这个操作完成,内存永远不会释放回来,直到数据库重新启动,它会消耗掉所有的15G内存

我想告诉KDB从内存中卸载一些表(但不要删除它们),但我不想重新启动DB,因为其他一些应用程序仍在连接它

有没有办法告诉KDB从内存中卸载某些内容

编辑:


如果有人觉得有趣,我建议大家看看KDB 2.5+,看起来很有希望。

以下是我的研究总结:

  • KDB之前的版本。2.5根据需要分配64MB内存块,并且从不释放它们。不过,它能够重用它们
  • 最近的KDB版本允许对垃圾收集器的请求调用(KDB使用ref.counting btw.)
  • 这在调用一些内存密集型计算时特别有用,这些计算分配了大量内存(在我的例子中是~20gB),并且希望在计算完成后释放内存
  • <> LI>您可以考虑将内存密集型脚本放在单独的Q过程中,这样,一旦脚本完成,内存将被释放。
这可能是显而易见的,但除了检查q版本的垃圾收集模式外,还要确保您已经实际清除了使用内存的内存中数据。如果您可以删除整个表(例如,这是计算中涉及的临时表),只需从根命名空间中删除它

delete table from`.
如果没有,则可以删除其所有行

delete from`table

对于将来尝试此方法的人,最简单的方法是:

  • 启动一个新的KDB进程
  • 从该流程查询中选择所需的最小有限数据子集
  • 从该进程执行任何连接/计算/写入文件。 (允许原件进行处理请求)
  • 关闭进程,释放所有内存
  • 如上所述,KDB的新版本可以更好地释放内存,但并不完美

    我们公司网站上有一篇很好的文章详细介绍了KDB+内存管理:

    我使用了一些不同的命令。只要您的表在删除之前存储在磁盘上,就应该可以了

    这是创建表之前的会话

    q).Q.w[]
    used| 290192
    heap| 67108864
    peak| 67108864
    wmax| 0
    mmap| 0
    mphy| 8589934592
    syms| 629
    symw| 20704
    
    此命令创建表,然后将其保存到磁盘

    q)t:([]10000?"ab"; 10000?5)
    q)save `t
    `:t
    
    这张桌子还在记忆中

    q).Q.w[]
    used| 437808
    heap| 67108864
    peak| 67108864
    wmax| 0
    mmap| 0
    mphy| 8589934592
    syms| 629
    symw| 20704
    
    让我们从内存中删除变量并进行垃圾收集

    q)delete t from `.
    `.
    q).Q.gc[]
    0
    
    现在,已使用的内存已减少到与会话开始时类似的数量

    q).Q.w[]
    used| 290208
    heap| 67108864
    peak| 67108864
    wmax| 0
    mmap| 0
    mphy| 8589934592
    syms| 630
    symw| 20730
    q)\v
    `symbol$()