【问题标题】:why does gprolog need so much RAM?为什么 gprolog 需要这么多内存?
【发布时间】:2013-01-10 01:36:48
【问题描述】:

以下来自top命令:

                            size  res 
1127 ***       1  20    0   117M  2196K ttyin   0   0:00  0.00% gprolog

1149 ***       1  23    0 10700K  3728K ttyin   0   0:00  0.00% swipl

它的RES是合理的,但它的大小与swipl相比太大了。

操作系统是freebsd 9.0。

真诚的!

【问题讨论】:

    标签: memory-management prolog swi-prolog gnu-prolog


    【解决方案1】:

    在您的 ps/top-listing 中有两个数字:分配的虚拟内存(大小)和实际使用的物理内存(资源)。由此看来,GNU Prolog 最初使用的内存比 SWI 少。即:GNU 为 2196K,SWI 为 3728K。

    但您无法仅从这些数字得出任何相关的结论。您唯一可以说的是,具有顶层的默认环境需要大量内存才能启动 - 前提是您没有使用另一个程序“分页”进程......

    两个系统都试图将内存消耗保持在较低水平,但程度不同:

    GNU Prolog 为跳过未使用的内置谓词的独立可执行文件提供编译。可执行代码的处理方式与 C 类似:因此它以只读方式映射到物理内存中。如果您运行此类可执行文件的多个实例,它们都将为可执行文件共享相同的物理内存。

    不利的一面是,GNU Prolog 缺乏垃圾收集。对于堆(copystack)和原子(可符号化)。为了避免溢出处理,内存区域被大量分配。但这只是对虚拟内存的保留。据我所知,所有当前的 Unix 变体都会过度使用虚拟内存,因此这不会占用相应的交换空间。

    另一方面,SWI-Prolog 将其 Prolog 代码分配到可写内存中。此外,在 GC 期间内存被“触及”(标记/未标记)。因此,Prolog 程序不能在不同的 SWI 实例之间共享,即使 dynamic re-sharing like mergemem 也不能。也就是说,mergemem(或类似的)可以页面共享它,但在下一次 db-GC 时,它是写时复制不共享的。请参阅链接如何共享可以减少 SICStus 的内存消耗。但是 SWI 具有多线程支持,这在一定程度上促进了共享。

    SWI 拥有最好和最完整的堆和原子垃圾收集器之一。

    因此,您的里程可能会有所不同。毫无疑问,最好的系统将两者的优点结合起来。

    【讨论】:

      【解决方案2】:

      gprolog 映射所有堆栈(其大小由环境变量控制)。默认值为16MB for the trail、约束和本地堆栈+ 32MB for the heap。还有原子表(也通过环境变量控制)。在大多数情况下,默认值很高。注意:因为这是虚拟内存(通过 mmap),它只在需要时才进行物理分配。所以分配大量内存并不是真正的问题(但是交换应该足以满足最大所需的内存)。无论如何,您可以重新定义它们(例如,如果您不使用 FD 求解器,您可以将 CSTRSZ env var 设置为 0)。

      SWI Prolog 会在需要时动态增加(我想减少)其内部堆栈的大小。所以一开始只需要很少的内存。

      【讨论】:

        猜你喜欢
        • 2017-09-14
        • 1970-01-01
        • 1970-01-01
        • 2014-02-08
        • 1970-01-01
        • 2017-05-22
        • 2014-11-25
        • 1970-01-01
        • 2014-08-29
        相关资源
        最近更新 更多