Hi all,
I am trying to understand how Julia decides when to call finalizers. I am using MathGL.jl for some plotting, and Julia doesn’t run the required finalizers for MGLGraphs until the end of the script, which makes it run out of memory and be killed when the amount of work becomes non-trivial.
The MathGL wrapper is huge, so I have a toy example below:
# File: memhungry.jl
type MemHungry
bite::Array{Int, 1}
end
function MemHungry(bitesize::Int)
info("A big bite of memory is now gone...")
m = MemHungry(Array{Int, 1}(bitesize))
finalizer(m, memregurgitate)
return m
end
function memregurgitate(m::MemHungry)
info("Wow, those blocks of memory sure tasted bad!")
info("Regurgitating.... Please wait.")
sleep(1)
info("Regurgitated $(length(m.bite)*8) bytes")
end
import Base.show
function show(io::IO, m::MemHungry)
for i in 1:length(m.bite)
info("Crunch, crunch crrunch!")
end
end
function munchmem(mealsize::Int)
m = MemHungry(mealsize)
info(m)
# finalize(m)
end
for i in 1:3
munchmem(i)
end
julia memhungry.jl
results in
INFO: A big bite of memory is now gone...
INFO: Crunch, crunch crrunch!
INFO:
INFO: A big bite of memory is now gone...
INFO: Crunch, crunch crrunch!
INFO: Crunch, crunch crrunch!
INFO:
INFO: A big bite of memory is now gone...
INFO: Crunch, crunch crrunch!
INFO: Crunch, crunch crrunch!
INFO: Crunch, crunch crrunch!
INFO:
jl_uv_writecb() ERROR: bad file descriptor EBADF
jl_uv_writecb() ERROR: bad file descriptor EBADF
jl_uv_writecb() ERROR: bad file descriptor EBADF
jl_uv_writecb() ERROR: bad file descriptor EBADF
jl_uv_writecb() ERROR: bad file descriptor EBADF
jl_uv_writecb() ERROR: bad file descriptor EBADF
jl_uv_writecb() ERROR: bad file descriptor EBADF
jl_uv_writecb() ERROR: bad file descriptor EBADF
jl_uv_writecb() ERROR: bad file descriptor EBADF
jl_uv_writecb() ERROR: bad file descriptor EBADF
jl_uv_writecb() ERROR: bad file descriptor EBADF
jl_uv_writecb() ERROR: bad file descriptor EBADF
jl_uv_writecb() ERROR: bad file descriptor EBADF
jl_uv_writecb() ERROR: bad file descriptor EBADF
jl_uv_writecb() ERROR: bad file descriptor EBADF
jl_uv_writecb() ERROR: bad file descriptor EBADF
jl_uv_writecb() ERROR: bad file descriptor EBADF
jl_uv_writecb() ERROR: bad file descriptor EBADF
jl_uv_writecb() ERROR: bad file descriptor EBADF
jl_uv_writecb() ERROR: bad file descriptor EBADF
jl_uv_writecb() ERROR: bad file descriptor EBADF
jl_uv_writecb() ERROR: bad file descriptor EBADF
jl_uv_writecb() ERROR: bad file descriptor EBADF
jl_uv_writecb() ERROR: bad file descriptor EBADF
jl_uv_writecb() ERROR: bad file descriptor EBADF
jl_uv_writecb() ERROR: bad file descriptor EBADF
jl_uv_writecb() ERROR: bad file descriptor EBADF
jl_uv_writecb() ERROR: bad file descriptor EBADF
jl_uv_writecb() ERROR: bad file descriptor EBADF
jl_uv_writecb() ERROR: bad file descriptor EBADF
If I uncomment the call to finalize(m)
in munchmem
, the output is
INFO: A big bite of memory is now gone...
INFO: MemHungry([0])
INFO: Wow, those blocks of memory sure tasted bad!
INFO: Regurgitating.... Please wait.
INFO: Regurgitated 8 bytes
INFO: A big bite of memory is now gone...
INFO: MemHungry([0,0])
INFO: Wow, those blocks of memory sure tasted bad!
INFO: Regurgitating.... Please wait.
INFO: Regurgitated 16 bytes
INFO: A big bite of memory is now gone...
INFO: MemHungry([0,0,0])
INFO: Wow, those blocks of memory sure tasted bad!
INFO: Regurgitating.... Please wait.
INFO: Regurgitated 24 bytes
So my question: Why does Julia have to be prodded like this to finalize things, even when (as with my plotting) memory is running low? Is there a way to avoid the prodding?
Thanks,
Lewis