web-dev-qa-db-ja.com

現在のRuby=プロセスのメモリ使用量を取得

長時間実行プロセスの一部として、Logger出力をフォーマットして現在のメモリ使用量を含めたいと思います。

Ruby、PHPの memory_get_usage() に少し似ているものに組み込みのものはありますか? psから?

51
d11wtq

1年前にこの問題を解決しようとしたとき、私は多くのオンライン調査と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)

これにより、プロセスの常駐メモリサイズが取得され、キロバイト単位でサイズ変数に格納されます。

少しの努力でこれをクリーンアップできますが、ほとんどの時間はpsを呼び出してその出力をキャプチャするために費やされるため、時間の価値はないと思います。

31
Paploo

NewRelic gemは、多数のオペレーティングシステムとRubyランタイムとその MemorySamplerクラス ]に対する単純なRSS使用の実装を提供します。

newrelic_rpm gemをGemfileに含めて呼び出します。

NewRelic::Agent::Samplers::MemorySampler.new.sampler.get_sample

また、現在のプロセスが保持しているメモリのメガバイト数をRSSとして返します。

実装では、利用可能なインプロセスカウンター(jruby)を優先し、Linuxでは/proc/#{$$}/statusを使用し、その他の場所ではpsにフォールバックします。

35
rud

Rubyでpsなどの外部コマンドを使用してバックティックを使用すると、コマンドの実行中に現在のプロセスがフォークされます。これは、Rubyプロセスが300mbを消費する場合、これらの`ps -o rss #{$$}`.strip.split.last.to_iソリューションのいずれかを実行するためにさらに300mbが必要になることを意味します。

Linuxベースのシステムでは、/proc/PID/statmを読み取ることでプロセスメモリ情報を取得できます。 2番目のフィールドは、カーネルページ数の常駐セットサイズです。 RSSページをバイトに変換するには、カーネルページサイズ(ほとんどの場合4096)を把握する必要があります。

Linuxで動作する、rsをキロバイト単位で取得するサンプルコードを次に示します。 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
12
Kimmo Lehto

OS gemにはrss_bytesメソッドがあります。

7
rogerdpack

このputsステートメントを簡単に使用できます

puts 'RAM USAGE: ' + `pmap #{Process.pid} | tail -1`[10,40].strip
6
apandey846