Skip to content

Commit

Permalink
Add Object Memory notes & examples
Browse files Browse the repository at this point in the history
  • Loading branch information
cema-sp committed Oct 25, 2016
1 parent 9f86c8c commit b5d6a2d
Show file tree
Hide file tree
Showing 3 changed files with 62 additions and 0 deletions.
11 changes: 11 additions & 0 deletions 019_obj_memory.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
puts "memory usage at start %d MB" % (`ps -o rss= -p #{Process.pid}`.to_i / 1024)

str = 'x' * 1024 * 1024 * 10 # 10 MB

puts "memory usage after allocation %d MB" % (`ps -o rss= -p #{Process.pid}`.to_i / 1024)

str = nil
GC.start(full_mark: true, immediate_sweep: true)

puts "memory usage after GC %d MB" % (`ps -o rss= -p #{Process.pid}`.to_i / 1024)

29 changes: 29 additions & 0 deletions 020_heap_gc.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
# require 'pretty_print'
require 'pp'

def stats
GC.stat.select { |k, v| %i(count heap_allocated_pages).include?(k) }
end

# ------ main ------

GC.start

puts "\tBefore allocation"
pp stats

x = Array.new(15_000) { Object.new }

puts "\tAfter 15.000 small objects allocation"
pp stats

x = nil

puts "\tAfter 15.000 small objects finalized"
pp stats

y = Array.new(15_000) { Object.new }

puts "\tAfter 15.000 more small objects allocation"
pp stats

22 changes: 22 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -435,3 +435,25 @@ Some GC stats (`GC.stat`) for Ruby 2.2:

Growth is the same as in Ruby 2.1 but relative to *eden* pages, not allocated pages.

### Object Memory

If Ruby object is bigger than half of 40 bytes (on 64-bit OS) it will be stored **entirely** outside the *objects heap*. This *object memory* will be freed and returned to OS after GC (see [019_obj_memory.rb](019_obj_memory.rb)).

Ruby string (`RSTRING` struct) can store only 23 bytes of payload.
`ObjectSpace.memsize_of(obj)` - shown object size in memory in bytes.

For example, 24 chars String will have size of 65 bytes (24 outside the heap + 1 for upkeep + 40 bytes inside heap).

It may be OK to allocate a big object in memory because it doesn't affect GC performance (but may lead to GC run), but it is crucial to allocate a large amount of small objects in *objects heap*.

## What triggers GC

Two main purposes are:

* No more free slots in the *objects heap* space
* Current memory allocation limit (malloc) has been exceeded

### Heap Usage

If there are no more free slots in *objects heap*, Ruby invokes GC to free *enough slots*, which is `max(allocated_slots * 0.2, GC_HEAP_FREE_SLOTS)` (see [020_heap_gc.rb](020_heap_gc.rb)).

0 comments on commit b5d6a2d

Please sign in to comment.