如何卸载OCaml插件?

时间:2014-12-02 23:15:05

标签: ocaml dynamic-linking

我想写一个

的程序
  1. 读取用户输入。
  2. 将其解释为OCaml源代码并将其写入临时.ml文件。
  3. 将文件编译为模块,插件或其他任何内容。
  4. 使用Dynlink.loadfile链接生成的对象。
  5. 从内存中卸载不再需要的代码。
  6. 我设法解决了前4个步骤:

    open Core.Std
    
    let () =
      let prog = read_line () in
      let oc = Out_channel.create "tmp.ml" in
    
      fprintf oc "%s" prog;
      Out_channel.close oc;
    
      Unix.waitpid_exn (Unix.fork_exec ~prog:"ocamlopt"
        ~args:["-c"; "-shared"; "-o"; "tmp.cmxs"; "tmp.ml"] ~use_path:true ());
    
      Dynlink.loadfile "tmp.cmxs"
    

    当看到这个程序用top执行时,我很明显地注意到在加载后使用的内存增加了。如果我在一个循环中重复这一点,这可能会很糟糕。

    甚至可以从内存中卸载代码吗?或者,当垃圾收集器看到我没有绑定到加载的对象时,它可能会自动完成吗?

1 个答案:

答案 0 :(得分:3)

简而言之,无法卸载代码。当然,只要不再需要,您就可以采取预防措施并卸载模块创建的任何数据结构作为副作用。

但代码无法删除,因为它存储在代码片段表中,永远不会被释放。

如果您想动态评估代码,我建议您使用compiler-libs,例如,这将为您评估表达式:

open Core_kernel.Std
open Or_error

let eval_exn str =
  let lexbuf = Lexing.from_string str in
  let phrase = !Toploop.parse_toplevel_phrase lexbuf in
  Toploop.execute_phrase false Format.err_formatter phrase

let eval str = try_with (fun () -> eval_exn str)