Logger
输出,以包含当前内存使用情况,用于长时间运行的过程的一部分。Ruby中是否有内置的功能可以实现这一点,有点像PHP的
memory_get_usage()
?还是我需要执行一些shell命令来从ps
获取它?Logger
输出,以包含当前内存使用情况,用于长时间运行的过程的一部分。memory_get_usage()
?还是我需要执行一些shell命令来从ps
获取它?一年前,我尝试解决此问题时,进行了大量的在线研究和API挖掘,只能通过调用ps系统调用来解决它。
在OS X 10.7.2和Red Hat 4.1.2-13(在EC2上)中都适用:
pid, size = `ps ax -o pid,rss | grep -E "^[[:space:]]*#{$$}"`.strip.split.map(&:to_i)
这个代码会获取当前进程的驻留内存大小(以千字节为单位),并将其放入size变量中。
虽然可以稍加修改来改进代码,但大部分时间都花在调用ps命令和捕获其输出上,因此我认为这样做不值得。
ps -o rss -p #{$$}.chomp.split("\n").last.to_i
,可能会更容易些。这句话的意思是获取当前进程的内存使用情况。 - Philip Csize = \
ps -o rss= -p #{$$}`.to_i或者
puts "%.1fMB used" % [`ps -o rss= -p #{$$}`.to_f/1024]` 更好更简洁,可以完成工作。它适用于Mac和Ubuntu。 - nonopolarityNewRelic gem提供了一些针对操作系统和ruby运行时的简单RSS使用实现,使用它们的MemorySampler
类。(参见此处)
在您的Gemfile
中包含newrelic_rpm
gem,并这样调用:
NewRelic::Agent::Samplers::MemorySampler.new.sampler.get_sample
返回当前进程占用的内存大小(以RSS表示),单位为兆字节。
实现时优先使用进程内计数器(例如jruby),在Linux上使用/proc/#{$$}/status
,其他情况下则回退到ps
。
ps
),并且以与被接受的答案相似的方式进行处理,还有针对不同平台的额外处理 :) (请查看上面的“MemorySampler类”链接) - Halil Özgürps
进程。在编写此文时,我无法找到任何其他获取正在运行进程信息的方法。我认为,在当今这个时代,其他地方描述的os
gem可能是更好的选择。 - rudos
gem 使用了相同类型的算法,在 Linux 上最终会生成 ps
进程:https://github.com/rdp/os/blob/a7256aa1eebdbab545212b7330131126f973aa14/lib/os.rb#L139-L170 - rud使用Ruby的外部命令(例如通过回引号使用ps
)将在运行命令期间分叉当前进程。这意味着,如果您的Ruby进程消耗了300MB,则需要另外300MB才能运行任何这些`ps -o rss #{$$}`.strip.split.last.to_i
解决方案。
在基于Linux的系统上,您可以通过读取/proc/PID/statm
来获取进程内存信息。第二个字段是以内核页面数为单位的常驻集大小(RSS)。将RSS页面转换为字节需要确定内核页大小(最有可能是4096)。
以下是一段示例代码,用于获取以千字节为单位的rss,在Linux上有效。我不知道如何在OSX或其他系统上执行此操作。
module MemInfo
# This uses backticks to figure out the pagesize, but only once
# when loading this module.
# You might want to move this into some kind of initializer
# that is loaded when your app starts and not when autoload
# loads this module.
KERNEL_PAGE_SIZE = `getconf PAGESIZE`.chomp.to_i rescue 4096
STATM_PATH = "/proc/#{Process.pid}/statm"
STATM_FOUND = File.exist?(STATM_PATH)
def self.rss
STATM_FOUND ? (File.read(STATM_PATH).split(' ')[1].to_i * KERNEL_PAGE_SIZE) / 1024 : 0
end
end
# >> MemInfo.rss
# => 251944
fork()
始终是写时复制,并且在分叉之后,Ruby将立即调用某种形式的exec()
。因此,进程不会存在足够长的时间来发生任何“不友好”的事情。 - Phil Frost您可以简单地使用此puts语句
puts 'RAM USAGE: ' + `pmap #{Process.pid} | tail -1`[10,40].strip
OS gem有一个rss_bytes方法。
require "os"
puts "#{OS.rss_bytes / 1_000_000} MB"
ps -o rss= -p #{Process.pid}
.to_i 在我的机器上大约为6毫秒,而最佳答案大约为11毫秒。 - Kalendaeps
,截至当前最新提交:https://github.com/rdp/os/blob/a7256aa1eebdbab545212b7330131126f973aa14/lib/os.rb#L139-L170 - rud时光流转,现在有一个针对此功能的宝石:get_process_mem
require 'get_process_mem'
mem = GetProcessMem.new
puts "Memory used : #{mem.mb.round(0)} MB"
在其他形式中已提及,但我发现这是最简单的咒语,至少在Mac OS上:
`ps -o rss #{Process.pid}`.lines.last.to_i
来自man ps
:
rss the real memory (resident set) size of the process (in 1024 byte units).