【问题标题】:Memory leak Sicstus Prolog内存泄漏 Sicstus Prolog
【发布时间】:2015-11-01 09:17:35
【问题描述】:

这个问题是question 的后续问题。

我在 Sicstus prolog 中运行大量测试:

runtest:-
 t1,
 t2,
 t3,
 .
 .
 t100.

每个测试都是独立的,并将其结果打印到屏幕上。测试之间没有关系,因此每次测试之间不需要存储/保存数据。

我的问题是Sicstus积累了内存,最后遇到异常:'Resource error:内存不足'

我尝试这样组织我的测试:

runtest:-
  once( t1 ),
  once( t2 ),
  .
  .
  once( t100 ).

但我还是遇到了问题。

有没有其他方法可以告诉 Prolog 在每次调用测试之间释放所有分配的内存?

【问题讨论】:

    标签: prolog clpfd sicstus-prolog


    【解决方案1】:

    不,没有办法告诉 Prolog 释放所有分配的内存。

    如果测试谓词不带参数,并且将它们包装在一次/1 中没有帮助,那么故障驱动循环也应该没有帮助。

    一种可能性是您的测试以某种方式添加了持久数据,例如断言子句。

    尝试添加

    garbage_collect,统计

    在(部分)测试之间。这应该让您了解哪些内存区域正在增长。

    从您之前的问题来看,可能是您的一个测试本身就耗尽了内存,即问题与运行多个测试无关。

    【讨论】:

    • undo 可能是once/1 无法回收空间的另一个原因。
    【解决方案2】:

    尝试使用(现代)failure driven loop:应该在 any Prolog 上回收内存

    ?- forall(member(T, [t1,t2,...,t100]), once(T)).
    

    【讨论】:

    • 在术语上将这种风格与常见的故障驱动循环区分开来会很有帮助。 findall/3setof/3 内部有故障驱动循环。
    • 不需要once(T),因为T 就足够了。
    【解决方案3】:

    谓词 once/1 仅删除选择点,但保留完整的线索。路径通常通过变量统一扩展或 即使受到约束求解器的约束。

    因此,您的测试链收集了大量数据。有一个 Prolog 民间传说 这会帮助你。使用双重否定释放资源,这个结构 因此通常被称为垃圾收集。

    只需将代码重写为:

    runtest:-
       \+ \+ t1,
       \+ \+ t2,
       \+ \+ t3,
       .
       .
       \+ \+ t100.
    

    但请注意,您的测试现在也将测量时间 拆除小径,可能会改变旧的结果,因为某个时候 拆除路径的时间是可以衡量的。

    最后但并非最不重要的当然是民间传说垃圾收集 双重否定仅在可以调用目标一次时才有效。

    再见

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-10-08
      • 2013-01-20
      • 2011-10-31
      • 2019-08-10
      • 2013-06-24
      相关资源
      最近更新 更多