在Julia释放记忆

Thu*_*ner 4 garbage-collection memory-management julia

我试图在朱莉娅释放记忆但没有成功.

function memuse()
  return string(round(Int,parse(Int,readall(`ps -p 29563 -o rss=`))/1024),"M")
end


function test()
  for i = 1:2   println("\ni=$i")
    a = rand(10000,10000)
    println("Created a $(memuse())")
    a = 0
    gc()
    println("Release a $(memuse())\n")

    b = rand(10000,10000)
    println("Created b $(memuse())")
    b = 0
    gc()
    println("Release b $(memuse())\n")

    c = rand(10000,10000)
    println("Created c $(memuse())")
    c =0
    gc()
    println("Release c $(memuse())\n")
  end
end
Run Code Online (Sandbox Code Playgroud)

输出:

i=1
Created a 918M 
Release a 918M

Created b 1681M
Release b 1681M

Created c 2444M
Release c 2444M


i=2
Created a 3207M
Release a 2444M

Created b 3207M
Release b 2444M

Created c 3207M
Release c 2444M
Run Code Online (Sandbox Code Playgroud)

此代码仅需要918M即可运行,但使用3207M.

问题: 为什么gc()没有释放未使用的内存?有一些方法可以强制垃圾收集器释放吗?为什么垃圾收集器只在第二次迭代时释放一些内存?

col*_*ang 6

来自JeffBezanson的GitHub问题

是的,这与代码生成方式有关.该rand呼叫归结为rand!(Array(T, dims)),和内部阵列保留在"参数堆栈"上,因为这些插槽普遍得到重用.在这种情况下将这些插槽归零是很好的,但必须非常小心地完成以避免添加大量不必要的存储.

您可以像这样解决方法:

@noinline function wrap()
    rand(10000,10000)
end

function test()
  for i = 1:2   println("\ni=$i")
    a = wrap()
    println("Created a $(memuse())")
    a = 0
    gc()
    println("Release a $(memuse())\n")

    b = wrap()
    println("Created b $(memuse())")
    b = 0
    gc()
    println("Release b $(memuse())\n")

    c = wrap()
    println("Created c $(memuse())")
    c =0
    gc()
    println("Release c $(memuse())\n")

  end
end
Run Code Online (Sandbox Code Playgroud)

请注意,@noinline以便清除堆栈.