Ruby's scripts are struggling with the phenomenon of keeping memory if it ever gets huge.
require 'objspace'
array=[ ]
(1..20).each_with_index do|i|
array<<'a'*1000000
puts "memsize:#{ObjectSpace.memsize_of_all/1024}KB, rss:#{`ps-orss=#{Process.pid}`.chomp}KB"
if i %5 == 0
array=[ ]
GC.start
puts "memsize:#{ObjectSpace.memsize_of_all/1024}KB, rss:#{`ps-orss=#{Process.pid}`.chomp}KB"
end
end
If you write code like this, the results will be as follows:
memsize:4125KB, rss:8016KB
memsize:5113KB, rss:9000KB
memsize: 6092 KB, rss: 10000 KB
memsize: 7071 KB, rss: 11000 KB
memsize: 8050 KB, rss: 11984 KB
memsize: 2473 KB, rss: 11988 KB
memsize:3452KB, rss:11988KB
memsize:4431KB, rss:11988KB
memsize:5410KB, rss:11988KB
memsize: 6389 KB, rss: 11988 KB
memsize: 7368KB, rss:11988KB
memsize: 2473 KB, rss: 11988 KB
memsize:3452KB, rss:11988KB
memsize:4431KB, rss:11988KB
memsize:5410KB, rss:11988KB
memsize: 6389 KB, rss: 11988 KB
memsize: 7368KB, rss:11988KB
memsize: 2473 KB, rss: 11988 KB
memsize:3452KB, rss:11988KB
memsize:4431KB, rss:11988KB
memsize:5410KB, rss:11988KB
memsize: 6389 KB, rss: 11988 KB
memsize: 7368KB, rss:11988KB
memsize: 2473 KB, rss: 11988 KB
I tried to extend the time and run the ps command from the outside, but no matter how I do it, RSS is not reduced.
The memory allocated to the Ruby object has been released, but it seems that the memory that was released will not be returned to the operating system.
It is good that we can reuse the memory we have reserved only for this process, but other processes are running on the server, so I would like to return the memory we no longer use to the operating system.
Is it difficult due to Ruby's specifications?
I remember Ruby as an implementation that is hard to get free even if the object is discarded.(It was a long time ago, so maybe it's different now?) Also, there are many implementations that call free does not return memory to the OS and reassign it the next time you malloc.
So, generally, we're going to program it on the premise that freeing up memory doesn't reduce the amount of memory we have.
If that's the case, you'll need to develop a fixed combination of Ruby's version (if any) and malloc/free implementation that frees up memory.
Ruby doesn't run out easily after rss increases to the maximum amount of memory used, so let's add more memory or load swaps.
Let's talk about MRI ruby.
Ruby, like any other process, has a heap and stack in addition to a static area, a program area (such as a ruby body or a library of native builds). Increasing rss in ruby's process is mostly due to enlarged heap.
There are two main types of data that the ruby program maintains on the heap:
Here are some of the ways to keep the data on each heap in memory:
In addition, the logic for each memory release is as follows:
And that is, ultimately, what matters is how malloc and free behave.And for glibc malloc/free, which ruby uses by default, the following conditions are required to return free memory to the operating system:
Because of this behavior, ruby (or rather long-term running programs for most dynamically malloc/free systems) has behavior such as keeping memory up to the maximum amount of memory used and not decreasing easily.
If there is a long-running program that uses a lot of memory only once in a while, I personally expect it to be swapped in/out well.
swap in/out.
We examined Ruby trends between 1.9 and 2.6 in Ubuntu 18.04 LTS on Windows Subsystem for Linux on Windows 10 Pro 1809 (64bit).Ruby is installed with rbenv-install.
In conclusion, I was able to confirm the decrease in rss for each version.However, the increase/decrease pattern and the amount of memory were different depending on the b version, so I couldn't grasp the trend.
--jit
.Looking at the release notes of each version, performance improvements around GC and memory are often made, and the way malloc is used and free is also changing.Also, if you enable jemalloc, there were different versions, so I think the ease of fragmentation will have an impact.
Therefore, this time, it seems that the OS did not recover the memory simply in the questioner's environment.See if a larger capacity (in hundreds of MB) really doesn't free up any memory.
© 2024 OneMinuteCode. All rights reserved.