How to get current Julia process memory usage?

I was debugging a ccall memory leak problem and found the memory usage value in top useful:

Is there a direct method to access this value from Julia? I used Sys.free_memory as a proxy but it suffers from noise introduced by other processes.

Made a workaround:

out = read(`top -bn1 -p $(getpid())`, String)
split(split(out,  "\n")[end-1])[6]
1 Like

In the same vein, you could also use ps:

julia> run(`ps -p $(getpid()) -o pid,comm,vsize,rss,size`);
4 Likes

Since you are using linux you might want to try reading "/proc/$(getpid())/mstat". You can a full description of the fields from:
https://man7.org/linux/man-pages/man5/proc.5.html

From the page:

Provides information about memory usage, measured in pages.
The columns are:

    size       (1) total program size
               (same as VmSize in /proc/[pid]/status)
    resident   (2) resident set size
               (same as VmRSS in /proc/[pid]/status)
    shared     (3) number of resident shared pages (i.e., backed by a file)
               (same as RssFile+RssShmem in /proc/[pid]/status)
    text       (4) text (code)
    lib        (5) library (unused since Linux 2.6; always 0)
    data       (6) data + stack
    dt         (7) dirty pages (unused since Linux 2.6; always 0)
2 Likes

pixel27 gives a solution without command:

open("/proc/$(getpid())/statm") do io
    split(read(io, String))[1]
end

But I still wonder if there is a cross platform solution so that memory leak checks can be written in the unit test / CI?

I believe it’s hard to determine programatically if there is a memory leak unless you are counting allocation and frees. Many of the allocation libraries allocate chunks of RAM from the OS then feed that out to the program in smaller chunks to improve allocation speed. So while the program is only actively using X amount of RAM Y amount (which is greater than X) will be allocated and I don’t think we as the end developer have much control over releasing that memory back to the system.

1 Like

Here’s at least a windows solution:

function memory()
    s = String(read(`tasklist /FI "PID eq $(getpid())" /NH /FO csv`))
    s = replace(s, "\"" => "")
    @info s
    m = strip(split(s, ",")[end])
    m = replace(m, "K" => "1000", "M" => "1000000", "G" => "1000000000")
    parse.(Float64, split(m)) |> prod |> Int
end

(I’m not sure, but it seems to me that Windows counts K as 1000 and not as 1024, etc.)

or this shorter one:

function memory()
    s = String(read(`tasklist /FI "PID eq $(getpid())" /NH /FO csv`))
    m = replace(match(r"""([^"]+)"[^"]+$""", s).captures[1],
        "K" => "1000", "M" => "1000000", "G" => "1000000000")
    parse.(Float64, split(m)) |> prod |> Int
end
1 Like