Module: Jemal

Extended by:
Interface
Defined in:
lib/jemal.rb,
lib/jemal/version.rb,
lib/jemal/interface.rb

Defined Under Namespace

Modules: Interface

Constant Summary collapse

CFG_PARAMS =
%i(debug dss fill lazy_lock mremap munmap prof prof_libgcc
prof_libunwind stats tcache tls utrace valgrind xmalloc)
OPT_BOOL =
%i(abort stats_print redzone zero utrace xmalloc tcache
prof prof_active prof_accum prof_gdump prof_final prof_leak)
OPT_SIZE_T =

4.0.0: prof_thread_active_init

%i(lg_chunk narenas quarantine lg_tcache_max)
OPT_SSIZE_T =
%i(lg_prof_sample lg_dirty_mult lg_prof_interval)
OPT_CHARP =
%i(dss junk prof_prefix)
GLOBAL_STATS =
%i(allocated active metadata resident mapped)
CHUNK_STATS =
%i(current total high)
ARN_SIZE_T =
%i(pactive pdirty mapped metadata.mapped metadata.allocated)
ARN_UINT64 =
%i(npurge nmadvise purged)
BIN_PARAMS =
%i(allocated nmalloc ndalloc nrequests)
BIN_SIZES =
%i(small large)
VERSION =
"0.1.1"

Class Method Summary collapse

Class Method Details

.arena_stats(i) ⇒ Object

Public: Get arena stats.

i - the Integer arena index (0..arenas_count-1).

Returns stats as a Hash.



192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
# File 'lib/jemal.rb', line 192

def self.arena_stats(i)
  prefix = "stats.arenas.#{i}."

  res = {
    #dss:           get_string("#{prefix}dss"),
    lg_dirty_mult: get_ssize_t("#{prefix}lg_dirty_mult"),
    nthreads:      get_uint("#{prefix}nthreads"),
  }

  ARN_SIZE_T.each { |p| res[p] = get_size_t("#{prefix}#{p}") }
  ARN_UINT64.each { |p| res[p] = get_uint64("#{prefix}#{p}") }

  BIN_SIZES.each do |sz|
    res[sz] = h = {}

    BIN_PARAMS.each do |p|
      h[p] = get_uint64("#{prefix}#{sz}.#{p}")
    end
  end

  res[:bins] = bins = {}
  bin_sizes = sizes[:bins]

  (0...bin_sizes.size).each do |i|
    binprefix = "#{prefix}bins.#{i}."
    nruns = get_uint64("#{binprefix}nruns")
    next if nruns == 0

    bins[bin_sizes[i][:size]] = {
      # Current number of bytes allocated by bin.
      allocated: get_size_t("#{binprefix}allocated"),

      # Cumulative number of allocations served by bin.
      nmalloc: get_uint64("#{binprefix}nmalloc"),

      # Cumulative number of allocations returned to bin.
      ndalloc: get_uint64("#{binprefix}ndalloc"),

      # Cumulative number of allocation requests.
      nrequests: get_uint64("#{binprefix}nrequests"),

      # Cumulative number of tcache fills.
      nfills: get_uint64("#{binprefix}nfills"),

      # Cumulative number of tcache flushes.
      nflushes: get_uint64("#{binprefix}nflushes"),

      # Cumulative number of times the current run from which to allocate changed.
      nreruns: get_uint64("#{binprefix}nreruns"),

      # Current number of runs.
      curruns: get_size_t("#{binprefix}curruns"),

      # Cumulative number of runs created.
      nruns: nruns
    }
  end

  res[:lruns] = lruns = {}
  lrun_sizes = sizes[:lruns]

  (0...lrun_sizes.size).each do |i|
    lrunprefix = "#{prefix}lruns.#{i}."
    nreqs = get_uint64("#{lrunprefix}nrequests")
    next if nreqs == 0

    lruns[lrun_sizes[i]] = {
      # Cumulative number of allocation requests for this size class served
      # directly by the arena.
      nmalloc: get_uint64("#{lrunprefix}nmalloc"),

      # Cumulative number of deallocation requests for this size class served
      # directly by the arena.
      ndalloc: get_uint64("#{lrunprefix}ndalloc"),

      # Cumulative number of allocation requests for this size class.
      nrequests: nreqs,

      # Current number of runs for this size class.
      curruns: get_size_t("#{lrunprefix}curruns"),
    }
  end

  res
end

.arenas_countObject

Public: Get current number of arenas.

Returns Integer value.



74
75
76
# File 'lib/jemal.rb', line 74

def self.arenas_count
  get_uint "arenas.narenas"
end

.build_configurationObject

Public: Get jemalloc build configuration.

Returns all config.* parameters in a single Hash.

Examples

Jemal.build_configuration
# => {:debug=>false, :dss=>false, :fill=>true, :lazy_lock=>false, ... }

Returns a Hash with Symbol keys and boolean values.



42
43
44
45
46
47
# File 'lib/jemal.rb', line 42

def self.build_configuration
  CFG_PARAMS.inject({}) do |hash, param|
    hash[param] = get_bool("config.#{param}")
    hash
  end
end

.initialized_arenasObject

Public: Get initialized arenas.

Returns a Set with integer arena indices. Every index is in

0, arenas_count-1

range.



82
83
84
85
86
87
88
89
90
91
92
93
94
# File 'lib/jemal.rb', line 82

def self.initialized_arenas
  n = arenas_count
  ptr = FFI::MemoryPointer.new :bool, n
  mallctl "arenas.initialized", ptr, size_pointer(ptr), nil, 0

  (0...n).inject(Set.new) do |indices, i|
    if ptr.get_uchar(i) > 0
      indices << i
    else
      indices
    end
  end
end

.jemalloc_builtin?Boolean

Public: Check if Ruby was built with jemalloc.

Returns true if it was, false otherwise.

Returns:

  • (Boolean)


11
12
13
14
15
# File 'lib/jemal.rb', line 11

def self.jemalloc_builtin?
  require 'rbconfig'

  !!(RbConfig::CONFIG["configure_args"] =~ /jemalloc/)
end

.optionsObject

Public: Get options (opt.*) as a Hash

Returns a Hash with 24 options.



52
53
54
55
56
57
58
59
60
61
# File 'lib/jemal.rb', line 52

def self.options
  res = {}

  OPT_BOOL.each    { |o| res[o] = get_bool("opt.#{o}") }
  OPT_SIZE_T.each  { |o| res[o] = get_size_t("opt.#{o}") }
  OPT_SSIZE_T.each { |o| res[o] = get_ssize_t("opt.#{o}") }
  OPT_CHARP.each   { |o| res[o] = get_string("opt.#{o}") }

  res
end

.sizesObject

Public: Get various sizes.

Page size, bin sizes, large run sizes, etc.

Sizes are believed to be constant, therefore this method result is cached. Second and successive calls will return cached value.

Returns a Hash with all sizes.



104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
# File 'lib/jemal.rb', line 104

def self.sizes
  return @sizes if defined?(@sizes)

  res = {
    # Quantum size
    quantum:   get_size_t("arenas.quantum"),
    # Page size
    page_size:  get_size_t("arenas.page"),
    # Maximum thread-cached size class
    tcache_max: get_size_t("arenas.tcache_max"),
    # Total number of thread cache bin size classes.
    nhbins: get_uint("arenas.nhbins")
  }

  # Number of bin size classes.
  nbins = get_uint("arenas.nbins")

  # Total number of large size classes.
  nlruns = get_uint("arenas.nlruns")

  # Total number of huge size classes (4.0.0)
  #nhchunks = get_uint("arenas.nhchunks")

  res[:bins] = (0...nbins).map do |i|
    prefix = "arenas.bin.#{i}."
    {
      # Maximum size supported by size class
      size: get_size_t("#{prefix}size"),
      # Number of regions per page run
      nregs: get_uint32("#{prefix}nregs"),
      # Number of bytes per page run
      run_size: get_size_t("#{prefix}run_size")
    }
  end

  res[:lruns] = (0...nlruns).map do |i|
    # Maximum size supported by this large size class
    get_size_t("arenas.lrun.#{i}.size")
  end

  # 4.0.0
  #res[:hchunks] = (0...nhchunks).map do |i|
    ## Maximum size supported by this huge size class
    #get_size_t("arenas.hchunk.#{i}.size")
  #end

  @sizes = res
end

.stats(refresh: true) ⇒ Object

Public: Get current statistics.

Returns stats as one big Hash.



156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
# File 'lib/jemal.rb', line 156

def self.stats(refresh: true)
  if refresh
    write_uint64("epoch", 1)
  end

  res = {}

  GLOBAL_STATS.each { |s| res[s] = get_size_t("stats.#{s}") }
  res[:cactive] = read_size_t(cactive_ptr)

  res[:chunks] = chunks = {}
  CHUNK_STATS.each { |s| chunks[s] = get_size_t("stats.chunks.#{s}") }

  res[:arenas] = arenas = Array.new(arenas_count)

  initialized_arenas.each do |i|
    arenas[i] = arena_stats(i)
  end

  res
end

.stats_printObject

Public: Print current stats.

Invoke jemalloc’s own stats reporting function, which prints all stats to STDERR.

Returns nothing.



284
285
286
# File 'lib/jemal.rb', line 284

def self.stats_print
  malloc_stats_print nil,nil,nil
end

.versionObject

Public: Get jemalloc version.

Examples

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

Returns the String version.



25
26
27
# File 'lib/jemal.rb', line 25

def self.version
  get_string "version"
end