Jemal

This gem provides interface to your MRI built with jemalloc. Of course you heard that Ruby 2.2.0 introduced jemalloc support.

Primary goal of this gem is to provide access to jemalloc statistics.

Currently jemalloc 3.6.0 is supported (certain Ruby gems can't yet be built with 4.0.0 due to stdbool.h conflict).

Note that there's another jemalloc-related gem on RubyGems. It doesn't provide interface to builtin jemalloc, but rather aims at injecting jemalloc in runtime with LD_PRELOAD.

Jemalloc installation

Ubuntu:

$ sudo apt-get install libjemalloc-dev

OS X:

$ brew install jemalloc

Note that if you want to use allocation profiling, you'll have to build jemalloc from source (./configure --enable-prof). Both ubuntu and homebrew versions are built without this option.

Ruby with jemalloc installation

Instructions are here.

Gem installation

Add this line to your application's Gemfile:

gem 'jemal'

And then execute:

$ bundle

Or install it yourself as:

$ gem install jemal

Usage

To be sure that your Ruby is jemalloc-powered, use Jemal.jemalloc_builtin?.

require 'jemal'

Jemal.jemalloc_builtin?
# => true

You can also check jemalloc version:

Jemal.version
# => "3.6.0-0-g46c0af68bd248b04df75e4f92d5fb804c3d75340"

Look at the flags jemalloc has been built with:

Jemal.build_configuration
# => {:debug=>false, :dss=>false, :fill=>true, :lazy_lock=>false, :mremap=>false, :munmap=>true,
#     :prof=>false, :prof_libgcc=>false, :prof_libunwind=>false, :stats=>true, :tcache=>true,
#     :tls=>false, :utrace=>false, :valgrind=>false, :xmalloc=>false}

Most of these options aren't very interesting, however be sure that Jemal.build_configuration[:stats] is true, otherwise you won't be able to collect statistics.

Find out how many arenas are used by jemalloc:

Jemal.arenas_count
# => 16

Each arena is basically a separate allocator with its own memory. Multiple arenas provide more speed for heavily multithreaded applications by allowing parallel threads to allocate memory simultaneously. This doesn't help MRI much, because its heap is still shared between all threads, so we can set MALLOC_CONF=narenas:1 in environment and have single arena.

Now to statistics:

Jemal.stats
# => {:allocated=>23587776, :active=>24416256, :metadata=>0, :resident=>0, :mapped=>29360128,
#     :cactive=>37748736, :chunks=>{:current=>7, :total=>7, :high=>7},
#     :arenas=>[ ... ]}

The returned hash is quite big, it contains joint statistics, as well as statistics for each arena. Read jemalloc man page to be able to understand the figures (look for stats.*).

If you just want human-compatible stats in text form and STDERR is okay, you are also covered:

Jemal.stats_print

You'll get a jemalloc stats dump which looks like this:

___ Begin jemalloc statistics ___
Version: 3.6.0-0-g46c0af68bd248b04df75e4f92d5fb804c3d75340
Assertions disabled
Run-time option settings:
  opt.abort: false
  opt.lg_chunk: 22
  opt.dss: "secondary"
  opt.narenas: 16
  opt.lg_dirty_mult: 3
  opt.stats_print: false
  opt.junk: false
  opt.quarantine: 0
  opt.redzone: false
  opt.zero: false
  opt.tcache: true
  opt.lg_tcache_max: 15
CPUs: 4
Arenas: 16
Pointer size: 8
Quantum size: 16
Page size: 4096
Min active:dirty page ratio per arena: 8:1
Maximum thread-cached size class: 32768
Chunk size: 4194304 (2^22)
Allocated: 23781096, active: 25649152, mapped: 33554432
Current active ceiling: 37748736
chunks: nchunks   highchunks    curchunks
              8            8            8
huge: nmalloc      ndalloc    allocated
            0            0            0

arenas[0]:
assigned threads: 1
dss allocation precedence: disabled
dirty pages: 6262:52 active:dirty, 0 sweeps, 0 madvises, 0 purged
            allocated      nmalloc      ndalloc    nrequests
small:       17493736       317316       120581       678822
large:        6287360          432           56         1269
total:       23781096       317748       120637       680091
active:      25649152
mapped:      29360128
bins:     bin  size regs pgs    allocated      nmalloc      ndalloc    nrequests       nfills     nflushes      newruns       reruns      curruns
            0     8  501   1        87688        12194         1233        19899          246           25           23           32           23
            1    16  252   1       200480        22361         9831        31078          279          113           81          162           52
            2    32  126   1      1017088        36067         4283        81314          433           57          267          373          264
            3    48   84   1      4174848       137466        50490       250234         1644          603         1140         3707         1072
            4    64   63   1       331392         9969         4791        35396          335           98          115          273          104
            5    80   50   1       691840        14013         5365        52709          353          122          197          682          182
            6    96   84   2       269664         3921         1112        12273           87           47           45           55           40
            7   112   72   2       433664         4481          609         7083           95           32           61           65           57
            8   128   63   2       207488         2086          465        11407           84           35           32           42           28
            9   160   51   2      2482880        49495        33977       106753          997          672          486         2895          313
           10   192   63   3       205632         1643          572         3659           61           42           24           24           19
           11   224   72   4       422688         2339          452         3222           62           35           31           17           28
           12   256   63   4       152320         1049          454         1383           51           39           19           11           11
           13   320   63   5      2549760         8587          619        11026          179           27          135           39          132
           14   384   63   6       167040          749          314         1105           29           38           11            3            8
           15   448   63   7       689472         2861         1322         5053          227           51           38           39           29
           16   512   63   8       161280          551          236          552           35           35           11            5            6
           17   640   51   8       693120         3729         2646        39605          119           74           42          224           25
           18   768   47   9       328704          677          249          723           36           36           15            8           10
           19   896   45  10       272384          560          256          660           36           35           14            9            7
           20  1024   63  16       273408          475          208          464           31           37            7            4            5
           21  1280   51  16       478720          686          312         1367           39           38           14            9            8
           22  1536   42  16       259584          323          154          545           40           34            6            3            5
           23  1792   38  17       236544          304          172          454           30           30            7            5            4
           24  2048   65  33       182272          236          147          198           29           30            3            1            2
           25  2560   52  33       245760          227          131          393           24           30            4            1            3
           26  3072   43  33       181248          156           97          173           30           30            3            7            2
           27  3584   39  35        96768          111           84           94           21           24            2            0            1
large:   size pages      nmalloc      ndalloc    nrequests      curruns
         4096     1           63           21          520           42
         8192     2           89           17          465           72
        12288     3           21            9           23           12
        16384     4          243            3          244          240
        20480     5            2            2            2            0
        24576     6            2            2            2            0
        28672     7            3            1            3            2
        32768     8            6            1            7            5
[11]
        81920    20            1            0            1            1
[2]
        94208    23            1            0            1            1
[232]
      1048576   256            1            0            1            1
[762]
--- End jemalloc statistics ---

Other methods of less interest:

Jemal.options       # Returns runtime jemalloc options
# => { :abort=>false, ... }

Jemal.sizes         # Returns some constant sizes (page, bin, lrun)
# => { :page_size=>4096, ... }

Contributing

Bug reports and pull requests are welcome on GitHub at https://github.com/be9/jemal.

License

The gem is available as open source under the terms of the MIT License.