Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.
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...
"G1 GC is an incremental parallel compacting
GC that provides more predictable pause times
compared to CMS GC and Parallel...
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: ...
#include<stdio.h>
int main()
{
int *ptr_one;
!
ptr_one = (int *)malloc(sizeof(int));
!
if (ptr_one == 0) {
printf("ERROR: ...
#include<stdio.h>
int main()
{
int *ptr_one;
!
ptr_one = (int *)malloc(sizeof(int));
!
if (ptr_one == 0) {
printf("ERROR: ...
#include<stdio.h>
int main()
{
int *ptr_one;
!
ptr_one = (int *)malloc(sizeof(int));
!
if (ptr_one == 0) {
printf("ERROR: ...
#include<stdio.h>
int main()
{
int *ptr_one;
!
ptr_one = (int *)malloc(sizeof(int));
!
if (ptr_one == 0) {
printf("ERROR: ...
#include<stdio.h>
int main()
{
int *ptr_one;
!
ptr_one = (int *)malloc(sizeof(int));
!
if (ptr_one == 0) {
printf("ERROR: ...
#include<stdio.h>
int main()
{
int *ptr_one;
!
ptr_one = (int *)malloc(sizeof(int));
!
if (ptr_one == 0) {
printf("ERROR: ...
#include<stdio.h>
int main()
{
int *ptr_one;
!
ptr_one = (int *)malloc(sizeof(int));
!
if (ptr_one == 0) {
printf("ERROR: ...
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 RBa...
typedef struct RVALUE {
union {
struct {
VALUE flags; /* always 0 for freed obj */
struct RVALUE *next;
} free;
struct RBa...
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 conservador...
• Slots de mesmo tamanho (não há problema com
fragmentação)
• Quanto mais heaps, mais lento
• Fase de marcação conservador...
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 ...
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 ...
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 ...
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 i...
• “Stop-and-Copy”
• Sweep precisa ir slot a slot, neste é só considerar
tudo no primeiro heap como livre
• Gerenciamento i...
• “Stop-and-Copy”
• Sweep precisa ir slot a slot, neste é só considerar
tudo no primeiro heap como livre
• Gerenciamento i...
• “Stop-and-Copy”
• Sweep precisa ir slot a slot, neste é só considerar
tudo no primeiro heap como livre
• Gerenciamento i...
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...
• Partial Markings, Lazy Sweeps = Menos Stop
• Shady objects não vão para o Tomb
• Write Barriers (referência old para new...
• Partial Markings, Lazy Sweeps = Menos Stop
• Shady objects não vão para o Tomb
• Write Barriers (referência old para new...
< 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...
@retained = []	
@rand = Random.new(999)	
!
MAX_STRING_SIZE = 100	
!
def stress(allocate_count, retain_count, chunk_size)	
...
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
...
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...
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_LI...
RUBY_GC_MALLOC_LIMIT_MAX 3210241024 8000000
RUBY_GC_OLDMALLOC_LIMIT_MAX 12810241024 8000000
RUBY_GC_HEAP_OLDOBJECT_LIMIT_F...
• 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 - Perman...
• Objetos vão para Tomb se sobreviverem 1 GC
• Objetos podem ir para Tomb cedo demais
• Eden - Survivor - Tenured - Perman...
• Objetos vão para Tomb se sobreviverem 1 GC
• Objetos podem ir para Tomb cedo demais
• Eden - Survivor - Tenured - Perman...
• Objetos vão para Tomb se sobreviverem 1 GC
• Objetos podem ir para Tomb cedo demais
• Eden - Survivor - Tenured - Perman...
Java
• Young Generation
• -XX:+UseSerialGC (copying collector)
• -XX:+UseParallelGC (copying collector multi-thread)
• -XX...
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 rec...
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
Ruby & GCs (versão 2.1.2) - VI Secot UFScar Sorocaba
Ruby & GCs (versão 2.1.2) - VI Secot UFScar Sorocaba
Ruby & GCs (versão 2.1.2) - VI Secot UFScar Sorocaba
Ruby & GCs (versão 2.1.2) - VI Secot UFScar Sorocaba
Ruby & GCs (versão 2.1.2) - VI Secot UFScar Sorocaba
Ruby & GCs (versão 2.1.2) - VI Secot UFScar Sorocaba
Ruby & GCs (versão 2.1.2) - VI Secot UFScar Sorocaba
Ruby & GCs (versão 2.1.2) - VI Secot UFScar Sorocaba
Ruby & GCs (versão 2.1.2) - VI Secot UFScar Sorocaba
Ruby & GCs (versão 2.1.2) - VI Secot UFScar Sorocaba
Ruby & GCs (versão 2.1.2) - VI Secot UFScar Sorocaba
Ruby & GCs (versão 2.1.2) - VI Secot UFScar Sorocaba
Ruby & GCs (versão 2.1.2) - VI Secot UFScar Sorocaba
Ruby & GCs (versão 2.1.2) - VI Secot UFScar Sorocaba
Ruby & GCs (versão 2.1.2) - VI Secot UFScar Sorocaba
Ruby & GCs (versão 2.1.2) - VI Secot UFScar Sorocaba
Ruby & GCs (versão 2.1.2) - VI Secot UFScar Sorocaba
Ruby & GCs (versão 2.1.2) - VI Secot UFScar Sorocaba
Ruby & GCs (versão 2.1.2) - VI Secot UFScar Sorocaba
Ruby & GCs (versão 2.1.2) - VI Secot UFScar Sorocaba
Ruby & GCs (versão 2.1.2) - VI Secot UFScar Sorocaba
Ruby & GCs (versão 2.1.2) - VI Secot UFScar Sorocaba
Ruby & GCs (versão 2.1.2) - VI Secot UFScar Sorocaba
Ruby & GCs (versão 2.1.2) - VI Secot UFScar Sorocaba
Ruby & GCs (versão 2.1.2) - VI Secot UFScar Sorocaba
Ruby & GCs (versão 2.1.2) - VI Secot UFScar Sorocaba
Ruby & GCs (versão 2.1.2) - VI Secot UFScar Sorocaba
Ruby & GCs (versão 2.1.2) - VI Secot UFScar Sorocaba
Ruby & GCs (versão 2.1.2) - VI Secot UFScar Sorocaba
Ruby & GCs (versão 2.1.2) - VI Secot UFScar Sorocaba
Ruby & GCs (versão 2.1.2) - VI Secot UFScar Sorocaba
Ruby & GCs (versão 2.1.2) - VI Secot UFScar Sorocaba
Ruby & GCs (versão 2.1.2) - VI Secot UFScar Sorocaba
Ruby & GCs (versão 2.1.2) - VI Secot UFScar Sorocaba
Ruby & GCs (versão 2.1.2) - VI Secot UFScar Sorocaba
Ruby & GCs (versão 2.1.2) - VI Secot UFScar Sorocaba
Ruby & GCs (versão 2.1.2) - VI Secot UFScar Sorocaba
Ruby & GCs (versão 2.1.2) - VI Secot UFScar Sorocaba
Ruby & GCs (versão 2.1.2) - VI Secot UFScar Sorocaba
Ruby & GCs (versão 2.1.2) - VI Secot UFScar Sorocaba
Ruby & GCs (versão 2.1.2) - VI Secot UFScar Sorocaba
Ruby & GCs (versão 2.1.2) - VI Secot UFScar Sorocaba
Ruby & GCs (versão 2.1.2) - VI Secot UFScar Sorocaba
Ruby & GCs (versão 2.1.2) - VI Secot UFScar Sorocaba
Ruby & GCs (versão 2.1.2) - VI Secot UFScar Sorocaba
Ruby & GCs (versão 2.1.2) - VI Secot UFScar Sorocaba
Ruby & GCs (versão 2.1.2) - VI Secot UFScar Sorocaba
Ruby & GCs (versão 2.1.2) - VI Secot UFScar Sorocaba
Ruby & GCs (versão 2.1.2) - VI Secot UFScar Sorocaba
Ruby & GCs (versão 2.1.2) - VI Secot UFScar Sorocaba
Ruby & GCs (versão 2.1.2) - VI Secot UFScar Sorocaba
Ruby & GCs (versão 2.1.2) - VI Secot UFScar Sorocaba
Ruby & GCs (versão 2.1.2) - VI Secot UFScar Sorocaba
Ruby & GCs (versão 2.1.2) - VI Secot UFScar Sorocaba
Ruby & GCs (versão 2.1.2) - VI Secot UFScar Sorocaba
Ruby & GCs (versão 2.1.2) - VI Secot UFScar Sorocaba
Ruby & GCs (versão 2.1.2) - VI Secot UFScar Sorocaba
Ruby & GCs (versão 2.1.2) - VI Secot UFScar Sorocaba
Ruby & GCs (versão 2.1.2) - VI Secot UFScar Sorocaba
Ruby & GCs (versão 2.1.2) - VI Secot UFScar Sorocaba
Ruby & GCs (versão 2.1.2) - VI Secot UFScar Sorocaba
Ruby & GCs (versão 2.1.2) - VI Secot UFScar Sorocaba
Ruby & GCs (versão 2.1.2) - VI Secot UFScar Sorocaba
Ruby & GCs (versão 2.1.2) - VI Secot UFScar Sorocaba
Ruby & GCs (versão 2.1.2) - VI Secot UFScar Sorocaba
Ruby & GCs (versão 2.1.2) - VI Secot UFScar Sorocaba
Ruby & GCs (versão 2.1.2) - VI Secot UFScar Sorocaba
Ruby & GCs (versão 2.1.2) - VI Secot UFScar Sorocaba
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

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

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

  1. 1. Ruby & GCs Entendendo Gerenciamento de Memória
  2. 2. "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."
  3. 3. "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."
  4. 4. Obsoletos 1.8.6 1.8.7 1.9.2
  5. 5. Obsoletos 1.8.6 1.8.7 1.9.2 Atuais 1.9.3 2.0.0 2.1.2
  6. 6. Alocação de Memória malloc() Limpeza de Lixo free()
  7. 7. #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; }
  8. 8. #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; }
  9. 9. #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; }
  10. 10. #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; }
  11. 11. #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; }
  12. 12. #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
  13. 13. #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
  14. 14. #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; }
  15. 15. Alocação de Memória malloc() Detecção de Lixo ? Limpeza de Lixo free()
  16. 16. 40 bytes livres
  17. 17. Slot (40 bytes) Heap (ex 6 slots)
  18. 18. Slot (40 bytes) Heap (ex 6 slots) Instância de RVALUE
  19. 19. 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
  20. 20. 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
  21. 21. Slot (40 kb) Heap (ex 6 slots) Instância de RVALUE Dados do RVALUE
  22. 22. Slot (40 kb) Heap (ex 6 slots) Instância de RVALUE Dados do RVALUE
  23. 23. Slot (40 kb) Heap (ex 6 slots) Instância de RVALUE Dados do RVALUE
  24. 24. Slot (40 kb) Heap (ex 6 slots) Instância de RVALUE Dados do RVALUE
  25. 25. Slot (40 kb) Heap (ex 6 slots) Instância de RVALUE Dados do RVALUE
  26. 26. Slot (40 kb) Heap (ex 6 slots) Instância de RVALUE Dados do RVALUE
  27. 27. Slot (40 kb) Heap (ex 6 slots) Instância de RVALUE Dados do RVALUE
  28. 28. Slot (40 kb) Heap (ex 6 slots) Instância de RVALUE Dados do RVALUE
  29. 29. Slot (40 kb) Heap (ex 6 slots) Instância de RVALUE Dados do RVALUE
  30. 30. Mark and Sweep GC Full Marking and Full Sweep GC
  31. 31. • Slots de mesmo tamanho (não há problema com fragmentação)
  32. 32. • Slots de mesmo tamanho (não há problema com fragmentação) • Quanto mais heaps, mais lento • Fase de marcação conservadora
  33. 33. • 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)
  34. 34. • 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"
  35. 35. Master Unicorn ou Passenger Rails App NGINX request 150mb
  36. 36. Master Unicorn ou Passenger Rails App NGINX Rails App fork() request 150mb 150mb
  37. 37. Master Unicorn ou Passenger Rails App NGINX Rails App Rails App fork() fork() request 150mb 150mb 150mb
  38. 38. Copy on Write (CoW) só copia o trecho da memória quando for modificada
  39. 39. “Mark Bit Map”
  40. 40. “Mark Bit Map”
  41. 41. “Mark Bit Map”
  42. 42. “Mark Bit Map”
  43. 43. “Mark Bit Map”
  44. 44. Bitmap Marking GC Full Bitmap Marking and Full Sweep GC
  45. 45. Master Unicorn ou Passenger Rails App NGINX request 150mb
  46. 46. Master Unicorn ou Passenger Rails App NGINX Rails App fork() request 150mb 100mb
  47. 47. Master Unicorn ou Passenger Rails App NGINX Rails App Rails App fork() fork() request 150mb 100mb 100mb
  48. 48. Mark Sweep Mark Sweep Mark Sweep
  49. 49. Mark Mark Mark
  50. 50. Lazy Sweep GC Full Bitmap Marking and Lazy Sweep GC
  51. 51. https://gist.github.com/akitaonrails/10212233
  52. 52. http://u.akita.ws/samsaffron_ruby20
  53. 53. RUBY_GC_MALLOC_LIMIT=30000000 RUBY_HEAP_MIN_SLOTS=800000 bundle exec rails server
  54. 54. RUBY_GC_MALLOC_LIMIT 8.000.000 30.000.000
  55. 55. RUBY_GC_MALLOC_LIMIT 8.000.000 30.000.000 RUBY_HEAP_MIN_SLOTS 10.000 800.000
  56. 56. env_gc_malloc_limit_in_mb 7.6mb 26.6mb
  57. 57. env_gc_malloc_limit_in_mb 7.6mb 26.6mb total_gc_runs 105 65
  58. 58. env_gc_malloc_limit_in_mb 7.6mb 26.6mb total_gc_runs 105 65 heaps_with_used_slots 1.089 1.477
  59. 59. 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
  60. 60. 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
  61. 61. 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
  62. 62. 71.9Mb
  63. 63. 2.49Mb 71.9Mb
  64. 64. GC Anterior
  65. 65. Weak Generational Hypothesis “Most young objects die young"
  66. 66. Young Generation (Eden) Old Generation (Tomb)
  67. 67. Generational GC Copying Garbage Collector
  68. 68. From-Heap To-Heap
  69. 69. From-Heap To-Heap
  70. 70. From-Heap To-Heap
  71. 71. From-Heap To-Heap
  72. 72. From-Heap To-Heap
  73. 73. From-Heap To-Heap
  74. 74. From-Heap To-Heap
  75. 75. Mark-Compact GC Mark Copy Compact Heap Swap GC
  76. 76. • “Stop-and-Copy”
  77. 77. • “Stop-and-Copy” • Sweep precisa ir slot a slot, neste é só considerar tudo no primeiro heap como livre
  78. 78. • “Stop-and-Copy” • Sweep precisa ir slot a slot, neste é só considerar tudo no primeiro heap como livre • Gerenciamento interno de ponteiros
  79. 79. • “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
  80. 80. • “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
  81. 81. • “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
  82. 82. Ruby 2.1.x Shady vs Non-Shady
  83. 83. Ruby Array
  84. 84. Ruby Object Ruby Array
  85. 85. Ruby Object Write Barrier (Non-Shady only) Ruby Array
  86. 86. Shady Object Non-Shady Object (Sunny)
  87. 87. Mark bitmap (mark_bits[]) Shady bitmap (rememberset_bits[])
  88. 88. Mark bitmap (mark_bits[]) Shady bitmap (rememberset_bits[])
  89. 89. Objetos "Old" 96.4%
  90. 90. Objetos "Old" 96.4% Objetos "Young" 3.6%
  91. 91. Objetos "Old" 96.4% Objetos "Young" 3.6% Objetos "Shady" 1.5%
  92. 92. Mark Mark Mark
  93. 93. Major GC Minor GC
  94. 94. 2.49Mb 71.9Mb
  95. 95. Restricted Generational GC (RGenGC) Full M&S for Shady, Generational for Non-Shady
  96. 96. • Partial Markings, Lazy Sweeps = Menos Stop
  97. 97. • Partial Markings, Lazy Sweeps = Menos Stop • Shady objects não vão para o Tomb
  98. 98. • 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)
  99. 99. • 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)
  100. 100. • 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
  101. 101. < 1.3! (+ major GC)
  102. 102. 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)
  103. 103. @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
  104. 104. Ruby 2.0 10 seg 119 mb Ruby 2.1.1 7 seg 230 mb ruby stress.rb http://u.akita.ws/ruby212ready
  105. 105. 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
  106. 106. 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
  107. 107. 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
  108. 108. 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/
  109. 109. • Objetos vão para Tomb se sobreviverem 1 GC
  110. 110. • Objetos vão para Tomb se sobreviverem 1 GC • Objetos podem ir para Tomb cedo demais
  111. 111. • Objetos vão para Tomb se sobreviverem 1 GC • Objetos podem ir para Tomb cedo demais • Eden - Survivor - Tenured - Permanent
  112. 112. • 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)
  113. 113. • 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)
  114. 114. • 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)
  115. 115. Java • Young Generation • -XX:+UseSerialGC (copying collector) • -XX:+UseParallelGC (copying collector multi-thread) • -XX:+UseParNewGC • Old Generation • -XX:+UseParallelOldGC • -XX:+UseConcMarkSweepGC
  116. 116. Master Unicorn ou Passenger Rails App NGINX request 190ms
  117. 117. Master Unicorn ou Passenger Rails App NGINX Rails App Rails App request 190ms 190ms 190ms
  118. 118. Master Unicorn ou Passenger Rails App NGINX Rails App Rails App request 190ms 190ms 190ms 50ms de Full GC!
  119. 119. Master Unicorn ou Passenger Rails App NGINX Rails App request 140ms 140ms Executa Full GC quando não receber request
  120. 120. Master Unicorn ou Passenger Rails App NGINX Rails App Rails App request 140ms 140ms Full GC Executa Full GC quando não receber request
  121. 121. OOBGC Out-of-Band Major GC
  122. 122. http://tmm1.net/ruby21-oobgc/
  123. 123. Pausas foram de 125ms para 50ms http://tmm1.net/ruby21-oobgc/
  124. 124. CUIDADO!!
  125. 125. CUIDADO!!
  126. 126. http://u.akita.ws/rubymicroscope
  127. 127. Obrigado! @akitaonrails slideshare.net/akitaonrails www.akitaonrails.com

×