Massive memory leak in Julia due to tiny memory leak in C

The latest version (v4.9.2) of netCDF-C (a C library for outputting data in the network Common Data Form.) is known to have memory leak. The leaked memory is not more than several MBs (see this link). However, when I use NCDatasets.jl, which is a wrapper in Julia for netcdf-C, I find that the memory leak reaches several GBs in the demo below:

using Printf
using NCDatasets

function create_dummpy_netcdf()
    dset = NCDataset("output.nc", "c", format=:netcdf4)
    close(dset)
end

function output_dummy_netcdf()
    dset = NCDataset("output.nc", "a")
    zeros(Float64, 1024, 1024)
    close(dset)
end


function main()

    create_dummpy_netcdf()
    for i in 1:1000
        output_dummy_netcdf()

        @info Printf.@sprintf "Max. RSS:  %9.3f MiB\n" Sys.maxrss()/2^20
    end

end

main()

The total memory usage reaches 8.2 GiB in the end, which is roughly 1000 times the allocation of zeros(Float64, 1024, 1024). Removing zeros(Float64, 1024, 1024) in output_dummy_netcdf makes the total memory usage limited to 400 MiB. It seems to me that the memory leak in the C code is “amplified” by allocations in Julia.

It is related to this issue on GitHub. Alexander-Barth finds that this bug can be produced simply with ccall-ing functions in libnetcdf.so. I am bringing the discussion here because I think it is related to how Julia manages memory.

I have also tried using Valgrind to profile the heap memory usage. However, when running with Valgrind, this bug cannot be reproduced. If you know a better tool for profiling memory in Julia, please let me know.

This question has been posted on JuliaLang as #55794, as suggested by @d-netto.

1 Like

Could you open an issue on JuliaLang (Issues · JuliaLang/julia · GitHub)?

1 Like

cc: @Alexander-Barth

“Maximum RSS” means the maximum of the RSS since the process’s birth, i.e. the largest it has ever been. So this number tells you the largest amount of physical memory your process has ever been using at any one instant.

This doesn’t mean that Julia is leaking memory. The GC might simply have not run yet, since there is no memory pressure.

When I run this code locally:

With an @time in front of main.

[ Info: Max. RSS:    478.117 MiB
[ Info: Max. RSS:    478.117 MiB
  0.932792 seconds (753.56 k allocations: 7.865 GiB, 18.04% gc time, 22.93% compilation time)
2 Likes