

railsのActiveRecordですが、SQLのクエリー結果をキャッシュしていると思います。

ログに、

[code]

    モデル名 Load (0.8ms)  SELECT 以下略
    
[/code]

と Loadと出ればキャッシュに保存し、クエリーの実行時間も表示。

[code]

    CACHE (0.1ms)  SELECT 以下略
    
[/code]

と出れば、キャッシュから取得したことを示し、キャッシュから取得するのにかかった時間も表示。

と認識しております。  
さてでは、キャッシュしているメモリの量を表示することはできないのでしょうか？  
ログに出す方法ではなく、都度調べる方法でも構いません。


CC BY-SA 3.0
2015-11-03T08:05:40.823
18354
2015-11-05T15:31:17.840
9008
question
ruby-on-rails rails-activerecord
ActiveRecordのメモリ使用量を確認する方法は？


"ruby memory profiler"というキーワードでググると、いろいろ情報が挙がってきます。

  * [Ruby プロセスを追いかけるツール(プロファイラとか)10選 - sonots:blog](http://blog.livedoor.jp/sonots/archives/39380434.html)
  * [Ruby でラインメモリプロファイラ - Qiita](http://qiita.com/sonots/items/c14b3e3ca8e6f7dfb651)
  * [Rubyでのメモリ使用量調査 - Qiita](http://qiita.com/kinushu/items/a2ec4078410284b9856d)
  * [SamSaffron/memory_profiler](https://github.com/SamSaffron/memory_profiler)
  * [ruby-prof/ruby-prof](https://github.com/ruby-prof/ruby-prof)

実際に使ったことはないので具体的な方法を示すことはできませんが、上記のような情報源を調べていくと質問の回答が得られるかもしれません。


CC BY-SA 3.0
2015-11-03T23:48:39.457
18384
2015-11-03T23:48:39.457
85
18354
answer


# TL;DR

こんな感じのミドルウェアを差し込むと取れると思います。

[code]

    class QueryCacheProf
      def initialize(app)
        @app = app
      end
    
      def call(env)
        @app.call(env).tap do
          GC.start
          memsize_of_all_before_query_cache_cleared = ObjectSpace.memsize_of_all
          ActiveRecord::Base.connection.clear_query_cache
          GC.start
          memsize_of_query_cache = memsize_of_all_before_query_cache_cleared - ObjectSpace.memsize_of_all
          Rails.logger.info "memsize of query cache: #{memsize_of_query_cache}"
        end
      end
    end
    
    Rails.application.config.middleware.insert_after ActiveRecord::QueryCache, QueryCacheProf
    
[/code]

## リクエスト中のクエリにキャッシュが効く仕組み

`bundle exec rake middleware`を実行すると`use
ActiveRecord::QueryCache`の行が表示されるかと思います。

ActiveRecordが差し込むRackミドルウェアで、このミドルウェアがリクエスト中の同一クエリの結果をキャッシュしています。

具体的に差し込んでいる箇所は以下です。  
<https://github.com/rails/rails/blob/0c7916952e0f6110e10a2968cbdab5326f571924/activerecord/lib/active_record/railtie.rb#L19,L20>

具体的にQueryCacheのミドルウェアの実装を読むと以下のように`connection.
enable_query_cache!`を呼んだ後でリクエストを処理しており、  
<https://github.com/rails/rails/blob/0c7916952e0f6110e10a2968cbdab5326f571924/activerecord/lib/active_record/query_cache.rb#L34>

`enable_query_cache!`を呼んだあとでは`@query_cache_enabled`が設定され  
<https://github.com/rails/rails/blob/0c7916952e0f6110e10a2968cbdab5326f571924/activerecord/lib/active_record/connection_adapters/abstract/query_cache.rb#L39>

`@query_cache_enabled`が設定されている場合、select文の結果が`cache_sql`でキャッシュされます。  
<https://github.com/rails/rails/blob/0c7916952e0f6110e10a2968cbdab5326f571924/activerecord/lib/active_record/connection_adapters/abstract/query_cache.rb#L65,L68>

`cache_sql`を読むと`@query_cache`に実行結果がキャッシュされているのがわかると思います。  
ここにキャッシュされているサイズを測れば、どの程度メモリを消費しているかわかると思います。


CC BY-SA 3.0
2015-11-05T15:31:17.840
18444
2015-11-05T15:31:17.840
2599
18354
answer