Ruby & GCs (versão 2.1.2) - VI Secot UFScar Sorocaba
Upcoming SlideShare
Loading in...5
×
 

Ruby & GCs (versão 2.1.2) - VI Secot UFScar Sorocaba

on

  • 1,598 views

Versão 2.1.2 da palestra que apresentei na QCon 2014 e reapresentada na VI Secot da UFScar Sorocaba.

Versão 2.1.2 da palestra que apresentei na QCon 2014 e reapresentada na VI Secot da UFScar Sorocaba.

Statistics

Views

Total Views
1,598
Views on SlideShare
817
Embed Views
781

Actions

Likes
6
Downloads
9
Comments
0

18 Embeds 781

http://www.akitaonrails.com 490
http://feedly.com 170
https://twitter.com 41
http://digg.com 22
http://192.168.6.184 14
http://feeds.feedburner.com 11
http://feedreader.com 7
http://feeds2read.net 7
http://www.inoreader.com 6
https://www.inoreader.com 2
http://newsblur.com 2
http://reader.aol.com 2
http://azariah2.rssing.com 2
http://www.feedspot.com 1
http://plus.url.google.com 1
http://embedresponsively.com 1
http://bealector.com 1
https://reader.aol.com 1
More...

Accessibility

Upload Details

Uploaded via as Adobe PDF

Usage Rights

© All Rights Reserved

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment

    Ruby & GCs (versão 2.1.2) - VI Secot UFScar Sorocaba Ruby & GCs (versão 2.1.2) - VI Secot UFScar Sorocaba Presentation Transcript

    • Ruby & GCs Entendendo Gerenciamento de Memória
    • "G1 GC is an incremental parallel compacting GC that provides more predictable pause times compared to CMS GC and Parallel Old GC. By introducing a parallel, concurrent and multi- phased marking cycle, G1 GC can work with much larger heaps while providing reasonable worst-case pause times."
    • "G1 GC is an incremental parallel compacting GC that provides more predictable pause times compared to CMS GC and Parallel Old GC. By introducing a parallel, concurrent and multi- phased marking cycle, G1 GC can work with much larger heaps while providing reasonable worst-case pause times."
    • Obsoletos 1.8.6 1.8.7 1.9.2
    • Obsoletos 1.8.6 1.8.7 1.9.2 Atuais 1.9.3 2.0.0 2.1.2
    • Alocação de Memória malloc() Limpeza de Lixo free()
    • #include<stdio.h> int main() { int *ptr_one; ! ptr_one = (int *)malloc(sizeof(int)); ! if (ptr_one == 0) { printf("ERROR: Out of memoryn"); return 1; } ! *ptr_one = 25; printf("%dn", *ptr_one); ! free(ptr_one); ! return 0; }
    • #include<stdio.h> int main() { int *ptr_one; ! ptr_one = (int *)malloc(sizeof(int)); ! if (ptr_one == 0) { printf("ERROR: Out of memoryn"); return 1; } ! *ptr_one = 25; printf("%dn", *ptr_one); ! free(ptr_one); ! return 0; }
    • #include<stdio.h> int main() { int *ptr_one; ! ptr_one = (int *)malloc(sizeof(int)); ! if (ptr_one == 0) { printf("ERROR: Out of memoryn"); return 1; } ! *ptr_one = 25; printf("%dn", *ptr_one); ! free(ptr_one); ! return 0; }
    • #include<stdio.h> int main() { int *ptr_one; ! ptr_one = (int *)malloc(sizeof(int)); ! if (ptr_one == 0) { printf("ERROR: Out of memoryn"); return 1; } ! *ptr_one = 25; printf("%dn", *ptr_one); ! free(ptr_one); ! return 0; }
    • #include<stdio.h> int main() { int *ptr_one; ! ptr_one = (int *)malloc(sizeof(int)); ! if (ptr_one == 0) { printf("ERROR: Out of memoryn"); return 1; } ! *ptr_one = 25; printf("%dn", *ptr_one); ! free(ptr_one); ! return 0; }
    • #include<stdio.h> int main() { int *ptr_one; ! ptr_one = (int *)malloc(sizeof(int)); ! if (ptr_one == 0) { printf("ERROR: Out of memoryn"); return 1; } ! *ptr_one = 25; printf("%dn", *ptr_one); ! free(ptr_one); ! return 0; } 0000 0000 0000 0000 0000 0000 0001 1001
    • #include<stdio.h> int main() { int *ptr_one; ! ptr_one = (int *)malloc(sizeof(int)); ! if (ptr_one == 0) { printf("ERROR: Out of memoryn"); return 1; } ! *ptr_one = 25; printf("%dn", *ptr_one); ! free(ptr_one); ! return 0; } 0000 0000 0000 0000 0000 0000 0001 1001
    • #include<stdio.h> int main() { int *ptr_one; ! ptr_one = (int *)malloc(sizeof(int)); ! if (ptr_one == 0) { printf("ERROR: Out of memoryn"); return 1; } ! *ptr_one = 25; printf("%dn", *ptr_one); ! free(ptr_one); ! return 0; }
    • Alocação de Memória malloc() Detecção de Lixo ? Limpeza de Lixo free()
    • 40 bytes livres
    • Slot (40 bytes) Heap (ex 6 slots)
    • Slot (40 bytes) Heap (ex 6 slots) Instância de RVALUE
    • typedef struct RVALUE { union { struct { VALUE flags; /* always 0 for freed obj */ struct RVALUE *next; } free; struct RBasic basic; struct RObject object; struct RClass klass; struct RFloat flonum; struct RString string; struct RArray array; struct RRegexp regexp; struct RHash hash; struct RData data; struct RTypedData typeddata; struct RStruct rstruct; struct RBignum bignum; struct RFile file; struct RNode node; struct RMatch match; struct RRational rational; struct RComplex complex; struct { struct RBasic basic; VALUE v1; VALUE v2; VALUE v3; } values; } as; #if GC_DEBUG const char *file; VALUE line; #endif } RVALUE; RVALUE
    • typedef struct RVALUE { union { struct { VALUE flags; /* always 0 for freed obj */ struct RVALUE *next; } free; struct RBasic basic; struct RObject object; struct RClass klass; struct RFloat flonum; struct RString string; struct RArray array; struct RRegexp regexp; struct RHash hash; struct RData data; struct RTypedData typeddata; struct RStruct rstruct; struct RBignum bignum; struct RFile file; struct RNode node; struct RMatch match; struct RRational rational; struct RComplex complex; struct { struct RBasic basic; VALUE v1; VALUE v2; VALUE v3; } values; } as; #if GC_DEBUG const char *file; VALUE line; #endif } RVALUE; RVALUE struct RString { struct RBasic basic; union { struct { long len; char *ptr; union { long capa; VALUE shared; } aux; } heap; char ary[RSTRING_EMBED_LEN_MAX + 1]; } as; }; RSTRING(str)->as.heap.ptr
    • Slot (40 kb) Heap (ex 6 slots) Instância de RVALUE Dados do RVALUE
    • Slot (40 kb) Heap (ex 6 slots) Instância de RVALUE Dados do RVALUE
    • Slot (40 kb) Heap (ex 6 slots) Instância de RVALUE Dados do RVALUE
    • Slot (40 kb) Heap (ex 6 slots) Instância de RVALUE Dados do RVALUE
    • Slot (40 kb) Heap (ex 6 slots) Instância de RVALUE Dados do RVALUE
    • Slot (40 kb) Heap (ex 6 slots) Instância de RVALUE Dados do RVALUE
    • Slot (40 kb) Heap (ex 6 slots) Instância de RVALUE Dados do RVALUE
    • Slot (40 kb) Heap (ex 6 slots) Instância de RVALUE Dados do RVALUE
    • Slot (40 kb) Heap (ex 6 slots) Instância de RVALUE Dados do RVALUE
    • Mark and Sweep GC Full Marking and Full Sweep GC
    • • Slots de mesmo tamanho (não há problema com fragmentação)
    • • Slots de mesmo tamanho (não há problema com fragmentação) • Quanto mais heaps, mais lento • Fase de marcação conservadora
    • • Slots de mesmo tamanho (não há problema com fragmentação) • Quanto mais heaps, mais lento • Fase de marcação conservadora • pode haver “leaks” (ex. constantes)
    • • Slots de mesmo tamanho (não há problema com fragmentação) • Quanto mais heaps, mais lento • Fase de marcação conservadora • pode haver “leaks” (ex. constantes) • Processo “Stop-the-World"
    • Master Unicorn ou Passenger Rails App NGINX request 150mb
    • Master Unicorn ou Passenger Rails App NGINX Rails App fork() request 150mb 150mb
    • Master Unicorn ou Passenger Rails App NGINX Rails App Rails App fork() fork() request 150mb 150mb 150mb
    • Copy on Write (CoW) só copia o trecho da memória quando for modificada
    • “Mark Bit Map”
    • “Mark Bit Map”
    • “Mark Bit Map”
    • “Mark Bit Map”
    • “Mark Bit Map”
    • Bitmap Marking GC Full Bitmap Marking and Full Sweep GC
    • Master Unicorn ou Passenger Rails App NGINX request 150mb
    • Master Unicorn ou Passenger Rails App NGINX Rails App fork() request 150mb 100mb
    • Master Unicorn ou Passenger Rails App NGINX Rails App Rails App fork() fork() request 150mb 100mb 100mb
    • Mark Sweep Mark Sweep Mark Sweep
    • Mark Mark Mark
    • Lazy Sweep GC Full Bitmap Marking and Lazy Sweep GC
    • https://gist.github.com/akitaonrails/10212233
    • http://u.akita.ws/samsaffron_ruby20
    • RUBY_GC_MALLOC_LIMIT=30000000 RUBY_HEAP_MIN_SLOTS=800000 bundle exec rails server
    • RUBY_GC_MALLOC_LIMIT 8.000.000 30.000.000
    • RUBY_GC_MALLOC_LIMIT 8.000.000 30.000.000 RUBY_HEAP_MIN_SLOTS 10.000 800.000
    • env_gc_malloc_limit_in_mb 7.6mb 26.6mb
    • env_gc_malloc_limit_in_mb 7.6mb 26.6mb total_gc_runs 105 65
    • env_gc_malloc_limit_in_mb 7.6mb 26.6mb total_gc_runs 105 65 heaps_with_used_slots 1.089 1.477
    • env_gc_malloc_limit_in_mb 7.6mb 26.6mb total_gc_runs 105 65 heaps_with_used_slots 1.089 1.477 total_heaps_allocated 1.958 1.965
    • env_gc_malloc_limit_in_mb 7.6mb 26.6mb total_gc_runs 105 65 heaps_with_used_slots 1.089 1.477 total_heaps_allocated 1.958 1.965 total_heaps_allocated_in_mb 30.6mb 30.7mb
    • env_gc_malloc_limit_in_mb 7.6mb 26.6mb total_gc_runs 105 65 heaps_with_used_slots 1.089 1.477 total_heaps_allocated 1.958 1.965 total_heaps_allocated_in_mb 30.6mb 30.7mb heaps_to_allocate_next_gc 869 0
    • 71.9Mb
    • 2.49Mb 71.9Mb
    • GC Anterior
    • Weak Generational Hypothesis “Most young objects die young"
    • Young Generation (Eden) Old Generation (Tomb)
    • Generational GC Copying Garbage Collector
    • From-Heap To-Heap
    • From-Heap To-Heap
    • From-Heap To-Heap
    • From-Heap To-Heap
    • From-Heap To-Heap
    • From-Heap To-Heap
    • From-Heap To-Heap
    • Mark-Compact GC Mark Copy Compact Heap Swap GC
    • • “Stop-and-Copy”
    • • “Stop-and-Copy” • Sweep precisa ir slot a slot, neste é só considerar tudo no primeiro heap como livre
    • • “Stop-and-Copy” • Sweep precisa ir slot a slot, neste é só considerar tudo no primeiro heap como livre • Gerenciamento interno de ponteiros
    • • “Stop-and-Copy” • Sweep precisa ir slot a slot, neste é só considerar tudo no primeiro heap como livre • Gerenciamento interno de ponteiros • Feito para corrigir fragmentação
    • • “Stop-and-Copy” • Sweep precisa ir slot a slot, neste é só considerar tudo no primeiro heap como livre • Gerenciamento interno de ponteiros • Feito para corrigir fragmentação • Ruby tem slots de mesmo tamanho
    • • “Stop-and-Copy” • Sweep precisa ir slot a slot, neste é só considerar tudo no primeiro heap como livre • Gerenciamento interno de ponteiros • Feito para corrigir fragmentação • Ruby tem slots de mesmo tamanho • Não suporta Copy-on-Write
    • Ruby 2.1.x Shady vs Non-Shady
    • Ruby Array
    • Ruby Object Ruby Array
    • Ruby Object Write Barrier (Non-Shady only) Ruby Array
    • Shady Object Non-Shady Object (Sunny)
    • Mark bitmap (mark_bits[]) Shady bitmap (rememberset_bits[])
    • Mark bitmap (mark_bits[]) Shady bitmap (rememberset_bits[])
    • Objetos "Old" 96.4%
    • Objetos "Old" 96.4% Objetos "Young" 3.6%
    • Objetos "Old" 96.4% Objetos "Young" 3.6% Objetos "Shady" 1.5%
    • Mark Mark Mark
    • Major GC Minor GC
    • 2.49Mb 71.9Mb
    • Restricted Generational GC (RGenGC) Full M&S for Shady, Generational for Non-Shady
    • • Partial Markings, Lazy Sweeps = Menos Stop
    • • Partial Markings, Lazy Sweeps = Menos Stop • Shady objects não vão para o Tomb
    • • Partial Markings, Lazy Sweeps = Menos Stop • Shady objects não vão para o Tomb • Write Barriers (referência old para new - non-Shady only)
    • • Partial Markings, Lazy Sweeps = Menos Stop • Shady objects não vão para o Tomb • Write Barriers (referência old para new - non-Shady only) • Compatível com extensões C (Shady)
    • • Partial Markings, Lazy Sweeps = Menos Stop • Shady objects não vão para o Tomb • Write Barriers (referência old para new - non-Shady only) • Compatível com extensões C (Shady) • Objetos em Tomb só são remarcados em Full Mark
    • < 1.3! (+ major GC)
    • RUBY_GC_HEAP_OLDOBJECT_LIMIT_FACTOR=1.3 bundle exec rails server força GC por diminuir o teto basicamente desabilita minor GC (de volta a Ruby 2.0.0)
    • @retained = [] @rand = Random.new(999) ! MAX_STRING_SIZE = 100 ! def stress(allocate_count, retain_count, chunk_size) chunk = []   while retain_count > 0 || allocate_count > 0     if retain_count == 0 || (@rand.rand < 0.5 && allocate_count > 0) chunk << " " * (@rand.rand * MAX_STRING_SIZE).to_i allocate_count -= 1       if chunk.length > chunk_size chunk = [] end else @retained << " " * (@rand.rand * MAX_STRING_SIZE).to_i retain_count -= 1 end end end ! start = Time.now # simulate rails boot, 2M objects allocated 600K retained in memory stress(2_000_000, 600_000, 200_000) ! # simulate 100 requests that allocate 100K objects stress(10_000_000, 0, 100_000) http://u.akita.ws/ruby212ready
    • Ruby 2.0 10 seg 119 mb Ruby 2.1.1 7 seg 230 mb ruby stress.rb http://u.akita.ws/ruby212ready
    • Ruby 2.0 10 seg 119 mb Ruby 2.1.1 7 seg 230 mb 1.3 6.85 seg 180 mb RUBY_GC_HEAP_OLDOBJECT_LIMIT_FACTOR=1.3 ruby stress.rb http://u.akita.ws/ruby212ready
    • Ruby 2.0 10 seg 119 mb Ruby 2.1.1 7 seg 230 mb 1.3 6.85 seg 180 mb 0.9 6.75 seg 146 mb RUBY_GC_HEAP_OLDOBJECT_LIMIT_FACTOR=0.9 ruby stress.rb http://u.akita.ws/ruby212ready
    • Ruby 2.0 10 seg 119 mb Ruby 2.1.1 7 seg 230 mb 1.3 6.85 seg 180 mb 0.9 6.75 seg 146 mb 8 mb 9 seg 117 mb RUBY_GC_MALLOC_LIMIT_MAX=8000000 RUBY_GC_OLDMALLOC_LIMIT_MAX=8000000 RUBY_GC_HEAP_OLDOBJECT_LIMIT_FACTOR=0.9 ruby stress.rb http://u.akita.ws/ruby212ready
    • RUBY_GC_MALLOC_LIMIT_MAX 3210241024 8000000 RUBY_GC_OLDMALLOC_LIMIT_MAX 12810241024 8000000 RUBY_GC_HEAP_OLDOBJECT_LIMIT_FACTOR 2.0 1.3 RUBY_GC_HEAP_INIT_SLOTS 10000 300000 RUBY_GC_HEAP_FREE_SLOTS 4096 300000 RUBY_GC_HEAP_GROWTH_FACTOR 1.8 1.25 RUBY_GC_HEAP_GROWTH_MAX_SLOTS (no limit) 150000 (obs: monitore, mensure, tuning, mensure de novo!) http://tmm1.net/ruby21-rgengc/
    • • Objetos vão para Tomb se sobreviverem 1 GC
    • • Objetos vão para Tomb se sobreviverem 1 GC • Objetos podem ir para Tomb cedo demais
    • • Objetos vão para Tomb se sobreviverem 1 GC • Objetos podem ir para Tomb cedo demais • Eden - Survivor - Tenured - Permanent
    • • Objetos vão para Tomb se sobreviverem 1 GC • Objetos podem ir para Tomb cedo demais • Eden - Survivor - Tenured - Permanent • RGENGC_THREEGEN mode (experimental 2.2)
    • • Objetos vão para Tomb se sobreviverem 1 GC • Objetos podem ir para Tomb cedo demais • Eden - Survivor - Tenured - Permanent • RGENGC_THREEGEN mode (experimental 2.2) • Parallel Marking (ex. em Thread separada) • Tri-Color Marking (talvez)
    • • Objetos vão para Tomb se sobreviverem 1 GC • Objetos podem ir para Tomb cedo demais • Eden - Survivor - Tenured - Permanent • RGENGC_THREEGEN mode (experimental 2.2) • Parallel Marking (ex. em Thread separada) • Tri-Color Marking (talvez) • Futuro: Incremental Major Phase (major GC menores)
    • Java • Young Generation • -XX:+UseSerialGC (copying collector) • -XX:+UseParallelGC (copying collector multi-thread) • -XX:+UseParNewGC • Old Generation • -XX:+UseParallelOldGC • -XX:+UseConcMarkSweepGC
    • Master Unicorn ou Passenger Rails App NGINX request 190ms
    • Master Unicorn ou Passenger Rails App NGINX Rails App Rails App request 190ms 190ms 190ms
    • Master Unicorn ou Passenger Rails App NGINX Rails App Rails App request 190ms 190ms 190ms 50ms de Full GC!
    • Master Unicorn ou Passenger Rails App NGINX Rails App request 140ms 140ms Executa Full GC quando não receber request
    • Master Unicorn ou Passenger Rails App NGINX Rails App Rails App request 140ms 140ms Full GC Executa Full GC quando não receber request
    • OOBGC Out-of-Band Major GC
    • http://tmm1.net/ruby21-oobgc/
    • Pausas foram de 125ms para 50ms http://tmm1.net/ruby21-oobgc/
    • CUIDADO!!
    • CUIDADO!!
    • http://u.akita.ws/rubymicroscope
    • Obrigado! @akitaonrails slideshare.net/akitaonrails www.akitaonrails.com