Also, I believe forking shouldn't actually double memory usage because of copy on write.
Also, I believe forking shouldn't actually double memory usage because of copy on write.
(Edit: ^happily I am wrong about this, though I believe the copy on write thing below is still correct, see further discussion)
Copy on write does definitely help here, only for Ruby > 2.0.
Why couldn't you just read /proc/self/status and /proc/self/smaps in process? Would be like an order of magnitude less expensive.
Best way to get the right answer on the internet is to post the wrong one.
> the only way to is shell out and scrape the output of ps
All `ps` is doing is reading files in proc. The memory info it prints is in `/proc/$pid/status`. Ruby can trivially read `/proc/self/status` to get that very naive view of how much memory it's using.
That isn't a useful amount of memory because, well, it doesn't actually show where object allocations go.
> Copy on write does definitely help here, only for Ruby > 2.0.
I believe she meant the operating system's copy-on-write of memory. Forking a copy of a process is actually very cheap because it's copy-on-write. That has nothing to do with ruby or its version and has been true in linux for as long as linux has existed.
I really don't understand what you're trying to say or why you mention ps at all.
Yep, great point, I am simply wrong about this.
> I believe she meant the operating system's copy-on-write of memory. Forking a copy of a process is actually very cheap because it's copy-on-write. That has nothing to do with ruby or its version and has been true in linux for as long as linux has existed.
Re: Copy on write the way Ruby implements GC in < 2.0 screws this up:
> The way ruby creates objects, the GC flag or reserved bit is stored in the object itself. So, as you would have guessed by now, when the GC runs in one of the processes, the GC flag would be modified in all the objects even if they are present in the shared pool. Now, the OS would sense this and trigger a copy-on-write making private copies of the objects in each child’s memory space.
https://medium.com/@rcdexta/whats-the-deal-with-ruby-gc-and-...
print File.readlines('/proc/self/status').select {|line| line =~ /VmRSS/}[0]
This is not what people mean when they talk about memory profiling, but it looked like what you were talking about, so I thought I'd share it.