我有3个ocaml模块,树的最后一个进行实际计算,并使用其他2个中定义的函数。
该程序的基本思想是将港口作为初始状态,其中包含船只,并移动这些船只,直到我们到达获胜局面或无法再有其他动作为止。 实际的代码在这里并不是真正的问题。它可能不是很有效,但是找到了解决方案……除非不是。
虽然程序在复杂情况下需要花费几秒钟的时间,但在某些情况下,当我增加一些复杂性时,要花很多时间才能找到解决方案。
当我执行这样的程序时:
$ ocamlc -o test.exe port.ml moves.ml solver.ml
$ ./test.exe > file
生成的文件确实很大,但是一段时间后它的大小停止增加。 在我看来,一段时间后程序停止运行,但没有终止,则不会引发Stackoverflow或内存不足错误。该程序根本不会继续执行。换句话说,命令
$ ./test.exe > file
仍被执行,但是没有更多新行添加到文件中。如果我登录到shell本身而不是文件,则得到相同的结果:一段时间后,不会再添加任何新行。
这可能是什么?
主要功能(负责查找解决方案)使用深度优先搜索算法,并且包含很多列表操作,例如List.fold,List.map,List .iter,List.partition,List.filter。我当时以为这些功能有时在处理庞大的复杂类型列表时会遇到问题,但同样,不会引发任何错误,执行会停止。
我对此含糊其辞,但我真的不明白这里的问题。我不知道问题是否与我的shell(Windows上的Ubuntu子系统)内存不足有关,还是ocaml List函数在某些时候受到限制...如果您有任何建议,请随时发表评论
答案 0 :(得分:1)
要调试此类情况,应使用操作系统和OCaml基础结构本身提供的诊断实用程序。
首先,您应调查过程的状态。如果您正在运行Unix计算机,则可以使用top
或htop
实用程序。否则,您可以使用任务管理器。
如果该进程用尽了物理内存,则操作系统可能会交换它。在这种情况下,所有内存操作都将变成硬盘驱动器读取和写入。因此,垃圾收集存储在硬盘驱动器中的堆将需要一些时间。如果是这种情况,那么您可以使用内存探查器来确定问题的症结所在。
如果进程不断运行而没有更改内存占用量,那么看起来您要么遇到了代码中的错误(即无限循环),要么您的某些算法具有指数复杂性(例如Konstantin)在评论中提到。使用调试输出或跟踪来确定程序停滞的位置。
最后,如果您的程序处于睡眠状态,则可能是死锁。例如,如果您正在读取和写入同一文件,则可能导致竞争。通常,如果您的程序是多线程的或运行多个进程,则有很多可能导致竞争状态。