SlideShare a Scribd company logo
Nasos Psarrakos
psarrakos@gmail.com
github.com/nasospsa
linkedin.com/in/nasos-psarrakos
Debugging Memory
Problems in Rails
The Problem
> A migration needs more than 1GB memory
> Memory @ Heroku: 512MB
def start_script
puts "starting script..."
# Remove the X to enable the parameters for tuning.
# These are the default values as of Ruby 2.2.0.
@child = spawn(<<-EOC.split.join(" "))
XRUBY_GC_HEAP_FREE_SLOTS=4096
XRUBY_GC_HEAP_INIT_SLOTS=10000
XRUBY_GC_HEAP_GROWTH_FACTOR=1.8
XRUBY_GC_HEAP_GROWTH_MAX_SLOTS=0
XRUBY_GC_HEAP_OLDOBJECT_LIMIT_FACTOR=2.0
XRUBY_GC_MALLOC_LIMIT=16777216
XRUBY_GC_MALLOC_LIMIT_MAX=33554432
XRUBY_GC_MALLOC_LIMIT_GROWTH_FACTOR=1.4
XRUBY_GC_OLDMALLOC_LIMIT=16777216
XRUBY_GC_OLDMALLOC_LIMIT_MAX=134217728
XRUBY_GC_OLDMALLOC_LIMIT_GROWTH_FACTOR=1.2
rails runner scripts/rbup.rb & echo $! >> tmp/pids/rbup.pid
EOC
sleep 0.1 until alive?
end
The problem 1/6
Script to check memory usage
def alive?
lines = `ps -p #{server_pid} | wc -l`.to_i
lines == 2
end
def stop_script
puts "stopping script..."
Process.kill :KILL, server_pid if server_pid && alive?
Process.wait @child
delete_pid
end
def delete_pid
`if test -f tmp/pids/rbup.pid; then rm tmp/pids/rbup.pid; fi`
end
def server_pid
`cat tmp/pids/rbup.pid`.to_i
end
def memory_size_mb
(`ps -o rss= -p #{server_pid}`.to_i * 1024).to_f / 2**20
end
https://gist.github.com/nasospsa/f7fadd6c2f3510b420525f960dc12ddd
The problem 2/6
Script to check memory usage
start_script
seconds = 0
used_mb = 0
max_mem = 0
while alive?
used_mb = memory_size_mb
max_mem = [max_mem, used_mb].max
puts "#{seconds}sec - #{'%.2f' % used_mb.round} MB"
seconds += 1
sleep 1
end
stop_script
puts "Total Time: #{seconds}sec"
puts "Max Memory: #{'%.2f' % max_mem} MB"
https://gist.github.com/nasospsa/f7fadd6c2f3510b420525f960dc12ddd
The problem 3/6
mapped = {}
fields = [:weights].concat(FoodsController::EAGER_LOADED_FIELDS)
Food.includes(*fields).find_each do |f|
mapped[f.id] = { json_data: f.as_json(methods: [:nutrient_data_basic]) }
end
Food.update(mapped.keys, mapped.values)
First iteration of the migration:
Result: Max Memory 1,1GB | 300 seconds
fields = [:weights].concat(FoodsController::EAGER_LOADED_FIELDS)
Food.includes(*fields).find_each do |f|
f.update json_data: f.as_json(methods: [:nutrient_data_basic])
end
The problem 4/6
Second iteration of the migration:
Result: Max Memory 1GB | 273 seconds
fields = [:weights].concat(FoodsController::EAGER_LOADED_FIELDS)
Food.includes(*fields).find_in_batches(batch_size: 200) do |group|
ActiveRecord::Base.transaction do
group.each do |f|
f.update json_data: f.as_json(methods: [:nutrient_data_basic])
end
end
end
The problem 5/6
Third iteration of the migration:
Result: Max Memory 380MB | 160 seconds
The problem 6/6
Fourth successful iteration of the migration:
Result: Max Memory 265MB | 82 seconds
fields = [:weights].concat(FoodsController::EAGER_LOADED_FIELDS)
Food.includes(*fields).find_in_batches(batch_size: 50) do |group|
group.each do |f|
f.update_columns json_data: f.as_json(methods: [:nutrient_data_basic])
end
end
update_columns(attributes)
Updates the attributes directly in the database issuing an
UPDATE SQL statement and sets them in the receiver.
This is the fastest way to update attributes because it goes
straight to the database, but take into account that in
consequence the regular update procedures are totally
bypassed.
3 Aha! Moments
> a moment of sudden insight or discovery.
1. Talk to other people.
2. Sleep on it.
3. Make a presentation.
psarrakos@gmail.com
github.com/nasospsa
linkedin.com/in/nasos-psarrakos
Thank
You

More Related Content

PPTX
App-o-Lockalypse now!
PDF
Data Consistency Workshop — Oslo Cassandra Users Oct 8, 2013
KEY
About memcached
PDF
MongoDB Database Replication
PDF
Javantura v2 - Replication with MongoDB - what could go wrong... - Philipp Krenn
PDF
Ruby 2.0 at the Ruby drink-up of Sophia, February 2013
PPT
Replica Sets (NYC NoSQL Meetup)
PPT
Os Secoske
App-o-Lockalypse now!
Data Consistency Workshop — Oslo Cassandra Users Oct 8, 2013
About memcached
MongoDB Database Replication
Javantura v2 - Replication with MongoDB - what could go wrong... - Philipp Krenn
Ruby 2.0 at the Ruby drink-up of Sophia, February 2013
Replica Sets (NYC NoSQL Meetup)
Os Secoske

What's hot (20)

PDF
ClickHouse Unleashed 2020: Our Favorite New Features for Your Analytical Appl...
ODP
OpenGurukul : Database : PostgreSQL
PDF
16 MySQL Optimization #burningkeyboards
PDF
uerj201212
PDF
PDF
MongoDb scalability and high availability with Replica-Set
PDF
PostgreSQL 9.6 새 기능 소개
PDF
Codigos
PDF
ClickHouse and the Magic of Materialized Views, By Robert Hodges and Altinity...
PDF
MongoUK 2011 - Rplacing RabbitMQ with MongoDB
PDF
ClickHouse materialized views - a secret weapon for high performance analytic...
ODP
MySQL 101 PHPTek 2017
PDF
Automating with ansible (Part c)
PDF
Практический опыт профайлинга и оптимизации производительности Ruby-приложений
PDF
"Ops Tools with Perl" 2012/05/12 Hokkaido.pm
ODP
Postgre sql unleashed
PPTX
Introduction to linux day1
PPTX
My sql failover test using orchestrator
PDF
MongoDB Tokyo - Monitoring and Queueing
PDF
PostgreSQL Replication Tutorial
ClickHouse Unleashed 2020: Our Favorite New Features for Your Analytical Appl...
OpenGurukul : Database : PostgreSQL
16 MySQL Optimization #burningkeyboards
uerj201212
MongoDb scalability and high availability with Replica-Set
PostgreSQL 9.6 새 기능 소개
Codigos
ClickHouse and the Magic of Materialized Views, By Robert Hodges and Altinity...
MongoUK 2011 - Rplacing RabbitMQ with MongoDB
ClickHouse materialized views - a secret weapon for high performance analytic...
MySQL 101 PHPTek 2017
Automating with ansible (Part c)
Практический опыт профайлинга и оптимизации производительности Ruby-приложений
"Ops Tools with Perl" 2012/05/12 Hokkaido.pm
Postgre sql unleashed
Introduction to linux day1
My sql failover test using orchestrator
MongoDB Tokyo - Monitoring and Queueing
PostgreSQL Replication Tutorial
Ad

Similar to Debugging Memory Problems in Rails (20)

ODP
Alexander Dymo - RailsConf 2014 - Improve performance: Optimize Memory and Up...
PPTX
GC Tuning: Fortune 500 Case Studies on Cutting Costs and Boosting Performance
PDF
Kickin' Ass with Cache-Fu (without notes)
 
PPTX
7 jvm-arguments-v1
PPTX
Java memory problem cases solutions
PDF
Using apache spark for processing trillions of records each day at Datadog
PDF
Adobe AEM Maintenance - Customer Care Office Hours
PPTX
Become a Java GC Hero - All Day Devops
PPTX
Java 어플리케이션 성능튜닝 Part1
PDF
MySQL Tokudb engine benchmark
PPTX
Think Distributed: The Hazelcast Way
PPTX
Distributed caching and computing v3.7
PDF
Troubleshooting Memory Problems in Java Applications
PDF
Ruby memory tips and tricks
PDF
Mastering java in containers - MadridJUG
PPTX
Top 5 Java Performance Problems Presentation!
PPTX
Am I reading GC logs Correctly?
PPT
Performance tuning jvm
PPTX
Become a Java GC Hero - ConFoo Conference
PDF
Memcached Study
Alexander Dymo - RailsConf 2014 - Improve performance: Optimize Memory and Up...
GC Tuning: Fortune 500 Case Studies on Cutting Costs and Boosting Performance
Kickin' Ass with Cache-Fu (without notes)
 
7 jvm-arguments-v1
Java memory problem cases solutions
Using apache spark for processing trillions of records each day at Datadog
Adobe AEM Maintenance - Customer Care Office Hours
Become a Java GC Hero - All Day Devops
Java 어플리케이션 성능튜닝 Part1
MySQL Tokudb engine benchmark
Think Distributed: The Hazelcast Way
Distributed caching and computing v3.7
Troubleshooting Memory Problems in Java Applications
Ruby memory tips and tricks
Mastering java in containers - MadridJUG
Top 5 Java Performance Problems Presentation!
Am I reading GC logs Correctly?
Performance tuning jvm
Become a Java GC Hero - ConFoo Conference
Memcached Study
Ad

Recently uploaded (20)

PDF
Why TechBuilder is the Future of Pickup and Delivery App Development (1).pdf
PDF
Adobe Premiere Pro 2025 (v24.5.0.057) Crack free
PDF
How to Choose the Right IT Partner for Your Business in Malaysia
PDF
How to Migrate SBCGlobal Email to Yahoo Easily
PDF
Navsoft: AI-Powered Business Solutions & Custom Software Development
PDF
Raksha Bandhan Grocery Pricing Trends in India 2025.pdf
PDF
PTS Company Brochure 2025 (1).pdf.......
PDF
System and Network Administration Chapter 2
PDF
Design an Analysis of Algorithms I-SECS-1021-03
PDF
Understanding Forklifts - TECH EHS Solution
PDF
top salesforce developer skills in 2025.pdf
PDF
wealthsignaloriginal-com-DS-text-... (1).pdf
PDF
AI in Product Development-omnex systems
PDF
medical staffing services at VALiNTRY
PDF
Which alternative to Crystal Reports is best for small or large businesses.pdf
PPTX
L1 - Introduction to python Backend.pptx
PPTX
Odoo POS Development Services by CandidRoot Solutions
PDF
T3DD25 TYPO3 Content Blocks - Deep Dive by André Kraus
PDF
Addressing The Cult of Project Management Tools-Why Disconnected Work is Hold...
PDF
Internet Downloader Manager (IDM) Crack 6.42 Build 42 Updates Latest 2025
Why TechBuilder is the Future of Pickup and Delivery App Development (1).pdf
Adobe Premiere Pro 2025 (v24.5.0.057) Crack free
How to Choose the Right IT Partner for Your Business in Malaysia
How to Migrate SBCGlobal Email to Yahoo Easily
Navsoft: AI-Powered Business Solutions & Custom Software Development
Raksha Bandhan Grocery Pricing Trends in India 2025.pdf
PTS Company Brochure 2025 (1).pdf.......
System and Network Administration Chapter 2
Design an Analysis of Algorithms I-SECS-1021-03
Understanding Forklifts - TECH EHS Solution
top salesforce developer skills in 2025.pdf
wealthsignaloriginal-com-DS-text-... (1).pdf
AI in Product Development-omnex systems
medical staffing services at VALiNTRY
Which alternative to Crystal Reports is best for small or large businesses.pdf
L1 - Introduction to python Backend.pptx
Odoo POS Development Services by CandidRoot Solutions
T3DD25 TYPO3 Content Blocks - Deep Dive by André Kraus
Addressing The Cult of Project Management Tools-Why Disconnected Work is Hold...
Internet Downloader Manager (IDM) Crack 6.42 Build 42 Updates Latest 2025

Debugging Memory Problems in Rails

  • 2. The Problem > A migration needs more than 1GB memory > Memory @ Heroku: 512MB
  • 3. def start_script puts "starting script..." # Remove the X to enable the parameters for tuning. # These are the default values as of Ruby 2.2.0. @child = spawn(<<-EOC.split.join(" ")) XRUBY_GC_HEAP_FREE_SLOTS=4096 XRUBY_GC_HEAP_INIT_SLOTS=10000 XRUBY_GC_HEAP_GROWTH_FACTOR=1.8 XRUBY_GC_HEAP_GROWTH_MAX_SLOTS=0 XRUBY_GC_HEAP_OLDOBJECT_LIMIT_FACTOR=2.0 XRUBY_GC_MALLOC_LIMIT=16777216 XRUBY_GC_MALLOC_LIMIT_MAX=33554432 XRUBY_GC_MALLOC_LIMIT_GROWTH_FACTOR=1.4 XRUBY_GC_OLDMALLOC_LIMIT=16777216 XRUBY_GC_OLDMALLOC_LIMIT_MAX=134217728 XRUBY_GC_OLDMALLOC_LIMIT_GROWTH_FACTOR=1.2 rails runner scripts/rbup.rb & echo $! >> tmp/pids/rbup.pid EOC sleep 0.1 until alive? end The problem 1/6 Script to check memory usage def alive? lines = `ps -p #{server_pid} | wc -l`.to_i lines == 2 end def stop_script puts "stopping script..." Process.kill :KILL, server_pid if server_pid && alive? Process.wait @child delete_pid end def delete_pid `if test -f tmp/pids/rbup.pid; then rm tmp/pids/rbup.pid; fi` end def server_pid `cat tmp/pids/rbup.pid`.to_i end def memory_size_mb (`ps -o rss= -p #{server_pid}`.to_i * 1024).to_f / 2**20 end https://gist.github.com/nasospsa/f7fadd6c2f3510b420525f960dc12ddd
  • 4. The problem 2/6 Script to check memory usage start_script seconds = 0 used_mb = 0 max_mem = 0 while alive? used_mb = memory_size_mb max_mem = [max_mem, used_mb].max puts "#{seconds}sec - #{'%.2f' % used_mb.round} MB" seconds += 1 sleep 1 end stop_script puts "Total Time: #{seconds}sec" puts "Max Memory: #{'%.2f' % max_mem} MB" https://gist.github.com/nasospsa/f7fadd6c2f3510b420525f960dc12ddd
  • 5. The problem 3/6 mapped = {} fields = [:weights].concat(FoodsController::EAGER_LOADED_FIELDS) Food.includes(*fields).find_each do |f| mapped[f.id] = { json_data: f.as_json(methods: [:nutrient_data_basic]) } end Food.update(mapped.keys, mapped.values) First iteration of the migration: Result: Max Memory 1,1GB | 300 seconds
  • 6. fields = [:weights].concat(FoodsController::EAGER_LOADED_FIELDS) Food.includes(*fields).find_each do |f| f.update json_data: f.as_json(methods: [:nutrient_data_basic]) end The problem 4/6 Second iteration of the migration: Result: Max Memory 1GB | 273 seconds
  • 7. fields = [:weights].concat(FoodsController::EAGER_LOADED_FIELDS) Food.includes(*fields).find_in_batches(batch_size: 200) do |group| ActiveRecord::Base.transaction do group.each do |f| f.update json_data: f.as_json(methods: [:nutrient_data_basic]) end end end The problem 5/6 Third iteration of the migration: Result: Max Memory 380MB | 160 seconds
  • 8. The problem 6/6 Fourth successful iteration of the migration: Result: Max Memory 265MB | 82 seconds fields = [:weights].concat(FoodsController::EAGER_LOADED_FIELDS) Food.includes(*fields).find_in_batches(batch_size: 50) do |group| group.each do |f| f.update_columns json_data: f.as_json(methods: [:nutrient_data_basic]) end end
  • 9. update_columns(attributes) Updates the attributes directly in the database issuing an UPDATE SQL statement and sets them in the receiver. This is the fastest way to update attributes because it goes straight to the database, but take into account that in consequence the regular update procedures are totally bypassed.
  • 10. 3 Aha! Moments > a moment of sudden insight or discovery.
  • 11. 1. Talk to other people.
  • 12. 2. Sleep on it.
  • 13. 3. Make a presentation.