0Pricing
Ruby Academy · Lesson

Memory Optimization

Reduce allocations.

Memory Optimization is a free Ruby Academy lesson on CoddyKit — lesson 3 of 4. You can read the complete lesson below for free — then practise it hands-on in the browser with a built-in code editor and a 24/7 AI tutor. It is part of the Ruby Academy learning path, one of 4 lessons in the course, and your progress syncs across the web and the CoddyKit app.

Why Memory Matters

Every object Ruby creates costs memory and adds garbage collection work. Fewer allocations means faster, leaner programs.

  • The GC pauses to reclaim objects
  • High allocation rates trigger more GC runs
  • Reducing allocations is often the biggest win
before = GC.stat(:total_allocated_objects)
100.times { 'new string' + '!' }
after = GC.stat(:total_allocated_objects)
puts "Allocated: #{after - before} objects"

Counting Allocations

GC.stat exposes allocation counters you can diff around a block.

  • :total_allocated_objects grows forever
  • Diff before and after to measure a section
def allocations
  before = GC.stat(:total_allocated_objects)
  yield
  GC.stat(:total_allocated_objects) - before
end

puts allocations { Array.new(1000) { |i| i.to_s } }

Frozen String Literals

Repeated string literals each allocate a new object. Freezing them lets Ruby reuse one immutable instance.

  • Add the magic comment at the top of a file
  • Or call .freeze on individual literals
# frozen_string_literal: true

s1 = 'hello'
s2 = 'hello'
puts s1.equal?(s2)

Avoid Allocations in Loops

Creating objects inside tight loops multiplies allocations. Hoist constants out.

  • Build regex, arrays, and strings once
  • Reuse them across iterations
PATTERN = /\d+/

def count_numbers(lines)
  lines.count { |line| line.match?(PATTERN) }
end

puts count_numbers(['a1', 'bb', 'c3'])

Mutating Methods (bang)

Non-bang methods return new objects; bang methods mutate in place, saving allocations.

  • map!, gsub!, sort!
  • Use only when mutating the original is safe
arr = [3, 1, 2]
arr.sort!
puts arr.inspect

s = 'hello world'
s.upcase!
puts s

Symbols vs Strings as Keys

Symbols are interned: the same symbol is one shared object. Use them for hash keys.

  • String keys allocate a new string each time
  • Symbols save memory in repeated lookups
puts :name.equal?(:name)
puts 'name'.equal?('name')

Lazy Enumerators

Chaining map and select builds intermediate arrays. lazy processes elements one at a time.

  • No intermediate collections allocated
  • Great for large or infinite sequences
result = (1..Float::INFINITY).lazy
  .select { |n| n.even? }
  .map { |n| n * n }
  .first(5)
puts result.inspect

Streaming Instead of Loading

Reading a whole file into memory is wasteful. Stream line by line instead.

  • each_line processes one line at a time
  • Constant memory regardless of file size
text = "line1\nline2\nline3"
text.each_line do |line|
  puts line.strip.upcase
end

String Concatenation

Building strings with + in a loop allocates a new string each time. Use << to append in place.

  • + creates a fresh object
  • << mutates the existing buffer
buffer = String.new
5.times { |i| buffer << "item#{i} " }
puts buffer

Object Pooling and Reuse

Reuse expensive objects instead of recreating them.

  • Cache parsed configs or compiled regex
  • Use a constant or memoized value
def config
  @config ||= { host: 'localhost', port: 4567 }
end

puts config.equal?(config)

Triggering GC for Insight

You can inspect GC behavior to confirm improvements.

  • GC.stat(:count) shows how many GC runs happened
  • Fewer runs after optimization is a good sign
start = GC.stat(:count)
50_000.times { |i| [i] }
puts "GC runs: #{GC.stat(:count) - start}"

Quick Check

Test your memory optimization knowledge.

Recap

You learned to optimize memory:

  • Count allocations with GC.stat
  • Freeze string literals and reuse objects
  • Prefer bang methods and << to avoid new objects
  • Use symbols for keys and lazy enumerators for pipelines
  • Stream large data instead of loading it all

Next you will tackle common performance bottlenecks.

Frequently asked questions

Is the “Memory Optimization” lesson free?

Yes — the full text of “Memory Optimization” is free to read here on the web, and the Ruby Academy course includes 4 lessons in total. To practise it interactively (a built-in code editor and a 24/7 AI tutor) and unlock the rest of the Ruby Academy course, upgrade to CoddyKit PRO.

What will I learn in “Memory Optimization”?

Reduce allocations. You practise Ruby Academy with hands-on code you run directly in the browser, and a 24/7 AI tutor answers your questions as you work through the lesson.

Do I need any experience to start Ruby Academy?

No prior experience is required. Ruby Academy on CoddyKit is structured for beginners through advanced learners; this is — lesson 3 of 4, so you can start here or from the beginning and move at your own pace.

How long does the “Memory Optimization” lesson take?

Most CoddyKit lessons take about 5–10 minutes. Each one is bite-sized and interactive, so you make steady progress and pick up exactly where you left off across the web and the app.

Can I write and run code in this Ruby Academy lesson?

Yes. Every Ruby Academy lesson includes a built-in code editor, so you write and run real code right in your browser and get instant AI feedback — no local setup required.

All lessons in this course

  1. Measuring Performance
  2. Profiling Tools
  3. Memory Optimization
  4. Common Bottlenecks
← Back to Ruby Academy