Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Memory Leaks, Tweaks, and Techniques

Memory Leaks, Tweaks, and Techniques

Avatar for Richard Schneeman

Richard Schneeman

November 07, 2015
Tweet

More Decks by Richard Schneeman

Other Decks in Programming

Transcript

  1. RAM

  2. #include <stdlib.h> void f(void) { int* x = malloc(10 *sizeof(int));

    x[10] = 0; } int main(void) { f(); return 0; }
  3. #include <stdlib.h> void f(void) { int* x = malloc(10 *sizeof(int));

    x[10] = 0; } int main(void) { f(); return 0; }
  4. $ valgrind --tool=memcheck ./memoryleak ==31747== Memcheck, a memory error detector

    ==31747== Copyright (C) 2002-2015, and GNU GPL'd, by Julian Seward et al. ==31747== Using Valgrind-3.11.0 and LibVEX; rerun with -h for copyright info ==31747== Command: ./memoryleak ==31747== ==31747== Invalid write of size 4 ==31747== at 0x100000F4C: f (memoryleak.c:6) ==31747== by 0x100000F73: main (memoryleak.c:10) ==31747== Address 0x100ae34a8 is 0 bytes after a block of size 40 alloc'd ==31747== at 0x100008EBB: malloc (in /usr/local/Cellar/valgrind/3.11.0/lib/ valgrind/vgpreload_memcheck-amd64-darwin.so) ==31747== by 0x100000F43: f (memoryleak.c:5) ==31747== by 0x100000F73: main (memoryleak.c:10) ==31747== ==31747== ==31747== HEAP SUMMARY: ==31747== in use at exit: 35,304 bytes in 431 blocks ==31747== total heap usage: 503 allocs, 72 frees, 41,272 bytes allocated ==31747== ==31747== LEAK SUMMARY: ==31747== definitely lost: 40 bytes in 1 blocks ==31747== indirectly lost: 0 bytes in 0 blocks ==31747== possibly lost: 0 bytes in 0 blocks ==31747== still reachable: 0 bytes in 0 blocks ==31747== suppressed: 35,264 bytes in 430 blocks ==31747== Rerun with --leak-check=full to see details of leaked memory ==31747== ==31747== For counts of detected and suppressed errors, rerun with: -v ==31747== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)
  5. $ valgrind --tool=memcheck ./memoryleak ==31747== Memcheck, a memory error detector

    ==31747== Copyright (C) 2002-2015, and GNU GPL'd, by Julian Seward et al. ==31747== Using Valgrind-3.11.0 and LibVEX; rerun with -h for copyright info ==31747== Command: ./memoryleak ==31747== ==31747== Invalid write of size 4 ==31747== at 0x100000F4C: f (memoryleak.c:6) ==31747== by 0x100000F73: main (memoryleak.c:10) ==31747== Address 0x100ae34a8 is 0 bytes after a block of size 40 alloc'd ==31747== at 0x100008EBB: malloc (in /usr/local/Cellar/valgrind/3.11.0/lib/ valgrind/vgpreload_memcheck-amd64-darwin.so) ==31747== by 0x100000F43: f (memoryleak.c:5) ==31747== by 0x100000F73: main (memoryleak.c:10) ==31747== ==31747== ==31747== HEAP SUMMARY: ==31747== in use at exit: 35,304 bytes in 431 blocks ==31747== total heap usage: 503 allocs, 72 frees, 41,272 bytes allocated ==31747== ==31747== LEAK SUMMARY: ==31747== definitely lost: 40 bytes in 1 blocks ==31747== indirectly lost: 0 bytes in 0 blocks ==31747== possibly lost: 0 bytes in 0 blocks ==31747== still reachable: 0 bytes in 0 blocks ==31747== suppressed: 35,264 bytes in 430 blocks ==31747== Rerun with --leak-check=full to see details of leaked memory ==31747== ==31747== For counts of detected and suppressed errors, rerun with: -v ==31747== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)
  6. $ valgrind --tool=memcheck ./memoryleak ==31747== Memcheck, a memory error detector

    ==31747== Copyright (C) 2002-2015, and GNU GPL'd, by Julian Seward et al. ==31747== Using Valgrind-3.11.0 and LibVEX; rerun with -h for copyright info ==31747== Command: ./memoryleak ==31747== ==31747== Invalid write of size 4 ==31747== at 0x100000F4C: f (memoryleak.c:6) ==31747== by 0x100000F73: main (memoryleak.c:10) ==31747== Address 0x100ae34a8 is 0 bytes after a block of size 40 alloc'd ==31747== at 0x100008EBB: malloc (in /usr/local/Cellar/valgrind/3.11.0/lib/ valgrind/vgpreload_memcheck-amd64-darwin.so) ==31747== by 0x100000F43: f (memoryleak.c:5) ==31747== by 0x100000F73: main (memoryleak.c:10) ==31747== ==31747== ==31747== HEAP SUMMARY: ==31747== in use at exit: 35,304 bytes in 431 blocks ==31747== total heap usage: 503 allocs, 72 frees, 41,272 bytes allocated ==31747== ==31747== LEAK SUMMARY: ==31747== definitely lost: 40 bytes in 1 blocks ==31747== indirectly lost: 0 bytes in 0 blocks ==31747== possibly lost: 0 bytes in 0 blocks ==31747== still reachable: 0 bytes in 0 blocks ==31747== suppressed: 35,264 bytes in 430 blocks ==31747== Rerun with --leak-check=full to see details of leaked memory ==31747== ==31747== For counts of detected and suppressed errors, rerun with: -v ==31747== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)
  7. Memory “1” “2” “3”“4” “5” “6” “7” RETAINED = []

    1.upto(100_000_000).each do |i| RETAINED << “#{i}” end
  8. def make_objects array = [] 1.upto(100_000_000).each do |i| array <<

    "#{i}" end return nil end make_objects GC.start(full_mark: true, immediate_sweep: true)
  9. def make_objects array = [] 1.upto(100_000_000).each do |i| array <<

    "#{i}" end return nil end make_objects GC.start(full_mark: true, immediate_sweep: true)
  10. def make_objects array = [] 1.upto(100_000_000).each do |i| array <<

    "#{i}" end return nil end make_objects GC.start(full_mark: true, immediate_sweep: true)
  11. WAT

  12. GC.start(full_mark: true, immediate_sweep: true) GC.disable # Code goes here before

    = GC.stat[:total_freed_objects] GC.enable GC.start(full_mark: true, immediate_sweep: true) after = GC.stat[:total_freed_objects] # => “Objects cleared by GC: 100_010_687”
  13. #include <stdlib.h> void f(void) { int* x = malloc(10 *sizeof(int));

    x[10] = 0; } int main(void) { f(); return 0; }
  14. No

  15. $ bundle exec derailed bundle:mem TOP: 54.1836 MiB mail: 18.9688

    MiB mime/types: 17.4453 MiB mail/field: 0.4023 MiB mail/message: 0.3906 MiB action_view/view_paths: 0.4453 MiB action_view/base: 0.4336 MiB
  16. $ bundle exec derailed exec perf:objects # ... ## allocated

    memory by location --------------------------------------- 1935548 /Users/richardschneeman/.gem/ruby/2.2.3/gems/actionpack-4.2.3/lib/action_dispa 896100 /Users/richardschneeman/.gem/ruby/2.2.3/gems/pg-0.16.0/lib/pg/result.rb:10 741488 /Users/richardschneeman/.gem/ruby/2.2.3/gems/activerecord-4.2.3/lib/active_rec 689299 /Users/richardschneeman/.gem/ruby/2.2.3/gems/activesupport-4.2.3/lib/active_su 660672 /Users/richardschneeman/.gem/ruby/2.2.3/gems/actionpack-4.2.3/lib/action_dispa 606384 /Users/richardschneeman/Documents/projects/codetriage/app/views/repos/\_repo.h 579384 /Users/richardschneeman/.gem/ruby/2.2.3/gems/activesupport-4.2.3/lib/active\_s 532800 /Users/richardschneeman/.gem/ruby/2.2.3/gems/actionpack-4.2.3/lib/action_dispa 391392 /Users/richardschneeman/.gem/ruby/2.2.3/gems/activerecord-4.2.3/lib/active_rec 385920 /Users/richardschneeman/.gem/ruby/2.2.3/gems/temple-0.7.5/lib/temple/utils.rb:
  17. $ PATH_TO_HIT=rails/rails bundle exec derailed exec perf:objects Booting: production Running

    1 times Total allocated: 21495556 bytes (207735 objects) Total retained: 15041423 bytes (133220 objects) allocated memory by gem ----------------------------------- 19427636 activerecord-4.2.3 1471380 activesupport-4.2.3 214048 actionview-4.2.3 151066 actionpack-4.2.3 121983 codetriage/app 24308 will_paginate-3.0.7 23193 rack-1.6.4 21105 arel-6.0.3 13397 ruby-2.2.3/lib 5560 warden-1.2.3 5536 rack-timeout-0.3.2 3912 activemodel-4.2.3 3000 hashie-3.4.2 2154 devise-3.5.2 1573 omniauth-1.2.2 1536 i18n-0.7.0 1495 railties-4.2.3 787 temple-0.7.6
  18. Per

  19. allocated memory by location ----------------------------------- 5131624 /Users/richardschneeman/.gem/ruby/2.2.3/gems/activerec 4616480 /Users/richardschneeman/.gem/ruby/2.2.3/gems/activerec 1336408

    /Users/richardschneeman/.gem/ruby/2.2.3/gems/activerec 1336088 /Users/richardschneeman/.gem/ruby/2.2.3/gems/activerec 1330904 /Users/richardschneeman/.gem/ruby/2.2.3/gems/activerec 1325648 /Users/richardschneeman/.gem/ruby/2.2.3/gems/activerec 921807 /Users/richardschneeman/.gem/ruby/2.2.3/gems/activesup 737376 /Users/richardschneeman/.gem/ruby/2.2.3/gems/activerec 596288 /Users/richardschneeman/.gem/ruby/2.2.3/gems/activerec 460720 /Users/richardschneeman/.gem/ruby/2.2.3/gems/activerec
  20. ???

  21. allocated objects by class ----------------------------------- 108939 String 35456 Hash 21605

    Array 5890 Proc 5886 RubyVM::Env 5859 ActiveRecord::Attribute::FromDatabase 5759 ActiveRecord::AttributeSet 5759 ActiveRecord::LazyAttributeHash 5731 ActiveRecord::Associations::BelongsToAssociation 5731 Issue 217 ActiveSupport::SafeBuffer 173 MatchData 112 ActionView::OutputBuffer 59 Time 43 ActiveRecord::Relation 42 ActiveRecord::ConnectionAdapters::PostgreSQL::Name 27 ActiveRecord::AssociationRelation 27 User }
  22. allocated objects by class ----------------------------------- 108939 String 35456 Hash 21605

    Array 5890 Proc 5886 RubyVM::Env 5859 ActiveRecord::Attribute::FromDatabase 5759 ActiveRecord::AttributeSet 5759 ActiveRecord::LazyAttributeHash 5731 ActiveRecord::Associations::BelongsToAssociation 5731 Issue 217 ActiveSupport::SafeBuffer 173 MatchData 112 ActionView::OutputBuffer 59 Time 43 ActiveRecord::Relation 42 ActiveRecord::ConnectionAdapters::PostgreSQL::Name 27 ActiveRecord::AssociationRelation 27 User }
  23. allocated objects by class ----------------------------------- 108939 String 35456 Hash 21605

    Array 5890 Proc 5886 RubyVM::Env 5859 ActiveRecord::Attribute::FromDatabase 5759 ActiveRecord::AttributeSet 5759 ActiveRecord::LazyAttributeHash 5731 ActiveRecord::Associations::BelongsToAssociation 5731 Issue 217 ActiveSupport::SafeBuffer 173 MatchData 112 ActionView::OutputBuffer 59 Time 43 ActiveRecord::Relation 42 ActiveRecord::ConnectionAdapters::PostgreSQL::Name 27 ActiveRecord::AssociationRelation 27 User
  24. allocated objects by class ----------------------------------- 108939 String 35456 Hash 21605

    Array 5890 Proc 5886 RubyVM::Env 5859 ActiveRecord::Attribute::FromDatabase 5759 ActiveRecord::AttributeSet 5759 ActiveRecord::LazyAttributeHash 5731 ActiveRecord::Associations::BelongsToAssociation 5731 Issue 217 ActiveSupport::SafeBuffer 173 MatchData 112 ActionView::OutputBuffer 59 Time 43 ActiveRecord::Relation 42 ActiveRecord::ConnectionAdapters::PostgreSQL::Name 27 ActiveRecord::AssociationRelation 27 User
  25. Started GET "/rails/rails" for ::1 at 2015-11-04 14:54:55 -0600 ActiveRecord::SchemaMigration

    Load (19.2ms) SELECT "schema_migrations".* FROM "schema_migration Processing by ReposController#show as HTML Parameters: {"full_name"=>"rails/rails"} Repo Load (21.2ms) SELECT "repos".* FROM "repos" WHERE "repos"."full_name" = $1 LIMIT 1 [["fu source=rack-timeout id=22a6fea79c2f050a9d9999b007298d12 timeout=30000ms service=1006ms state=activ Issue Load (1091.1ms) SELECT "issues".* FROM "issues" WHERE "issues"."repo_id" IN (36) source=rack-timeout id=22a6fea79c2f050a9d9999b007298d12 timeout=30000ms service=2093ms state=activ source=rack-timeout id=22a6fea79c2f050a9d9999b007298d12 timeout=30000ms service=3101ms state=activ source=rack-timeout id=22a6fea79c2f050a9d9999b007298d12 timeout=30000ms service=4027ms state=activ (48.1ms) SELECT COUNT(*) FROM "users" INNER JOIN "repo_subscriptions" ON "users"."id" = "repo_ User Load (53.4ms) SELECT "users".* FROM "users" INNER JOIN "repo_subscriptions" ON "users"."i Rendered subscribers/_avatars.html.slim (138.9ms) CACHE (0.0ms) SELECT COUNT(*) FROM "users" INNER JOIN "repo_subscriptions" ON "users"."id" = "r (0.6ms) SELECT COUNT(count_column) FROM (SELECT 1 AS count_column FROM "users" INNER JOIN "re 36]] Issue Load (41.8ms) SELECT "issues".* FROM "issues" WHERE "issues"."repo_id" = $1 AND "issues" (44.2ms) SELECT COUNT(*) FROM "issues" WHERE "issues"."repo_id" = $1 AND "issues"."state" = $2 Rendered repos/show.html.slim within layouts/application (496.5ms) source=rack-timeout id=22a6fea79c2f050a9d9999b007298d12 timeout=30000ms service=5005ms state=activ Rendered application/_head.html.slim (1360.4ms) Rendered application/_flashes.html.slim (15.9ms) Rendered application/_logo.html.slim (21.5ms) Rendered application/_nav.html.slim (73.0ms) Rendered application/_thoughtbot.html.slim (11.5ms) Rendered application/_footer.html.slim (36.4ms) Completed 200 OK in 5760ms (Views: 1889.1ms | ActiveRecord: 1323.2ms) source=rack-timeout id=22a6fea79c2f050a9d9999b007298d12 timeout=30000ms service=6004ms state=activ
  26. Started GET "/rails/rails" for ::1 at 2015-11-04 14:54:55 -0600 ActiveRecord::SchemaMigration

    Load (19.2ms) SELECT "schema_migrations".* FROM "schema_migration Processing by ReposController#show as HTML Parameters: {"full_name"=>"rails/rails"} Repo Load (21.2ms) SELECT "repos".* FROM "repos" WHERE "repos"."full_name" = $1 LIMIT 1 [["fu source=rack-timeout id=22a6fea79c2f050a9d9999b007298d12 timeout=30000ms service=1006ms state=activ Issue Load (1091.1ms) SELECT "issues".* FROM "issues" WHERE "issues"."repo_id" IN (36) source=rack-timeout id=22a6fea79c2f050a9d9999b007298d12 timeout=30000ms service=2093ms state=activ source=rack-timeout id=22a6fea79c2f050a9d9999b007298d12 timeout=30000ms service=3101ms state=activ source=rack-timeout id=22a6fea79c2f050a9d9999b007298d12 timeout=30000ms service=4027ms state=activ (48.1ms) SELECT COUNT(*) FROM "users" INNER JOIN "repo_subscriptions" ON "users"."id" = "repo_ User Load (53.4ms) SELECT "users".* FROM "users" INNER JOIN "repo_subscriptions" ON "users"."i Rendered subscribers/_avatars.html.slim (138.9ms) CACHE (0.0ms) SELECT COUNT(*) FROM "users" INNER JOIN "repo_subscriptions" ON "users"."id" = "r (0.6ms) SELECT COUNT(count_column) FROM (SELECT 1 AS count_column FROM "users" INNER JOIN "re 36]] Issue Load (41.8ms) SELECT "issues".* FROM "issues" WHERE "issues"."repo_id" = $1 AND "issues" (44.2ms) SELECT COUNT(*) FROM "issues" WHERE "issues"."repo_id" = $1 AND "issues"."state" = $2 Rendered repos/show.html.slim within layouts/application (496.5ms) source=rack-timeout id=22a6fea79c2f050a9d9999b007298d12 timeout=30000ms service=5005ms state=activ Rendered application/_head.html.slim (1360.4ms) Rendered application/_flashes.html.slim (15.9ms) Rendered application/_logo.html.slim (21.5ms) Rendered application/_nav.html.slim (73.0ms) Rendered application/_thoughtbot.html.slim (11.5ms) Rendered application/_footer.html.slim (36.4ms) Completed 200 OK in 5760ms (Views: 1889.1ms | ActiveRecord: 1323.2ms) source=rack-timeout id=22a6fea79c2f050a9d9999b007298d12 timeout=30000ms service=6004ms state=activ
  27. No

  28. allocated memory by location ----------------------------------- 5131624 active_record/result.rb:116 1336408 active_record/attribute_set/builder.rb:30 1336088

    active_record/persistence.rb:69 1330904 active_record/core.rb:547 1325648 active_record/attribute_methods.rb:359 921807 active_support/callbacks.rb:81 737376 active_record/core.rb:114 596288 active_record/associations.rb:162 460720 active_record/attribute_set/builder.rb:16