Successfully reported this slideshow.
Your SlideShare is downloading. ×

TDC2018SP | Trilha Go - Entendendo alocacao de memoria no Go

Ad

Entendendo alocação de
memória no Go
André Carvalho
@andresantostc
1

Ad

Desenvolvedor @ Globo.com
tsuru.io
https://andrestc.com
2

Ad

3

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Loading in …3
×

Check these out next

1 of 73 Ad
1 of 73 Ad

More Related Content

More from tdc-globalcode (20)

TDC2018SP | Trilha Go - Entendendo alocacao de memoria no Go

  1. 1. Entendendo alocação de memória no Go André Carvalho @andresantostc 1
  2. 2. Desenvolvedor @ Globo.com tsuru.io https://andrestc.com 2
  3. 3. 3
  4. 4. Por que? ● Conhecer os trade-offs ● Conhecer uma camada de abstração abaixo ● Porque não? 4
  5. 5. func main() { rand.Seed(time.Now().UnixNano()) i := rand.Intn(100) fmt.Printf("%v at %pn", i, &i) for { } } 5
  6. 6. 6 $ ./vmemory 53 at 0xc420016110 $ ./vmemory 68 at 0xc420016110 Rodando o programa duas vezes ao mesmo tempo... Mesmo endereço
  7. 7. Memória Virtual ● Processos não leem diretamente da memória física ○ Segurança ○ Coordenação entre múltiplos processos ● Memória Virtual abstrai isso dos processos ○ Segmentation ○ Page tables 7
  8. 8. Memória Virtual 8 Frame 0 Frame 1 Frame 2 Frame 3 Frame 4 Frame 5 Frame 6 Frame 7 RAM Disk Other process Page 0 Page 1 Page 2 Page 3 Page 4 Page 5 Page 6 Page 7 Page Process Frame Page Table 3 6
  9. 9. Layout de um Processo 9 Text Data Heap BSS Stack Program Break Code Initialized static variables Uninitialized static variables Dynamic allocated variables Function stack frames
  10. 10. Alocação na Stack 10 Stack Used Stack Pointer (SP) Unused Allocation SP += size; return Stack[SP-size]; Deallocation SP -= size;
  11. 11. Alocação na Heap ● Objetos com tamanho conhecido apenas em tempo de execução ● C tem malloc e free ● C++ tem new e delete ● Go usa escape analysis e garbage collection 11
  12. 12. Alocador Simples 12
  13. 13. Alocador Simples Precisamos implementar duas funções 13 void* malloc(size_t size) void free(void *ptr)
  14. 14. Alocador Simples 14 Application Allocator OS malloc mmap Alocador utiliza syscalls como mmap/munmap para falar com o OS munmap madvisefree
  15. 15. Alocador Simples Lista encadeada de objetos disponíveis size=n next=* Header n bytes size=m next=nil m bytes 15 Head
  16. 16. Alocador Simples - Alocação malloc(10) 16 Head NULL
  17. 17. Alocador Simples 17 Virtual Address Space 0x000000c000000000 mmap( 0x000000c000000000, 4096, PROT_WRITE | PROT_READ, MAP_PRIVATE | MAP_ANONYMOUS, ...) Start Address Size Permission Flags
  18. 18. Alocador Simples - Alocação malloc(10) 18 4084 12 4084 4096 Head
  19. 19. Alocador Simples - Alocação malloc(10) 19 4062Head 10 22
  20. 20. Alocador Simples - Alocação malloc(10) 20 4062Head 10 P Allocator returns p, which points right after the header
  21. 21. 21 Alocador Simples - Desalocação 4062Head free(p) 10
  22. 22. free(p) 10 p - size(header) 22 Alocador Simples - Desalocação 4062Head
  23. 23. Alocador Simples ● Pode ser implementado em algumas centenas de LOCs ● Questões não endereçadas ○ Fragmentação ○ Devolver memória para o OS ■ Quando? ■ Como? munmap, madvise... ○ Multi-thread ○ ... 23
  24. 24. Go Runtime Allocator 24 ● TCMalloc ● Invocando o Alocador ● Go’s Allocator
  25. 25. Thread-Caching Malloc (TCMalloc) ● Implementado originalmente em C pelo Google ● Serve como base para o algoritmo usado pelo Go ● Diminui lock-contention em programas multi-threaded 25
  26. 26. TCMalloc ● Cada thread tem um cache local ● Dois tipos de alocação ○ Small allocations (<= 32 kB) ○ Large allocations 26
  27. 27. TCMalloc - Small Allocations ● Atendidas pelo cache local da thread ● Tamanho é arredondado para o de uma das classes 27 malloc(965 bytes) ⇒ malloc(1024 bytes) malloc(1023 bytes) ⇒ malloc(1024 bytes)
  28. 28. TCMalloc - Small Allocations Class 0 Class 1 Class 2 ... Local Thread Cache 28
  29. 29. TCMalloc - Small Allocations Class 0 Class 1 Class 2 ... Local Thread Cache 29
  30. 30. TCMalloc - Small Allocations Class 0 Class 1 Class 2 ... Local Thread Cache Span Span Span ... Central Free List Class 1 30 Run of contiguous pagesSpan
  31. 31. TCMalloc - Small Allocations Class 0 Class 1 Class 2 ... Local Thread Cache Span Span Span ... Central Free List Class 1 31
  32. 32. TCMalloc - Small Allocations Span Span Span Central Free List Class X Span 1 page 2 pages ... > 255 pages Span Span Span Span Span Span Span Central Heap 32
  33. 33. TCMalloc - Small Allocations Span Span Span Central Free List Class X Span 1 page 2 pages ... > 255 pages Span Span Span Span Span Span Central Heap Span ... 33 Span
  34. 34. TCMalloc - Small Allocations Application Local Thread Cache Central Free List Central Heap 4 bytes N 8-byte objects X pages OS Y*X pages 34 X pages N 8-byte objects Y*X pages
  35. 35. TCMalloc - Large Allocations ● Atendidas pela Heap central ● Tamanho é arredondado para numero de paginas 35 malloc(34 kB) ⇒ malloc(36 kB) ⇒ 9 pages malloc(33 kB) ⇒ malloc(36 kB) ⇒ 9 pages
  36. 36. TCMalloc - Large Allocations 1 page 2 pages ... > 255 pages Span Span Span Span Span Span Central Heap Span Span 36
  37. 37. TCMalloc - Deallocation Page 1 Page 2 Page 3 Page 4 Page 5 Page 6 Span A Span B Span C 37
  38. 38. TCMalloc - Deallocation free( ) Page Span 38
  39. 39. TCMalloc - Deallocation free( ) Page Span Class 0 Class 1 Class 2 ... Local Thread Cache Small object 39
  40. 40. TCMalloc - Deallocation free( ) Page Span Large object Page 1 Page 2 Page 3 Page 4 Span A Span B Span C 40
  41. 41. TCMalloc - Deallocation free( ) Page Span Large object Page 1 Page 2 Page 3 Page 4 Span A Span B 41
  42. 42. TCMalloc - Deallocation free( ) Page Span Large object 1 page 2 pages ... > 255 pages Span B Central Heap 42
  43. 43. TCMalloc - Deallocation free( ) Page Span Large object 1 page 2 pages ... > 255 pages Span B Central Heap 43
  44. 44. Go Runtime Allocator 44 ● TCMalloc ● Invocando o Alocador ● Go’s Allocator
  45. 45. package main func main() { f() } //go:noinline func f() *int { i := 10 return &i } 45
  46. 46. package main func main() { f() } //go:noinline func f() *int { i := 10 return &i } 46 $ go build -gcflags "-m -m" main.go # command-line-arguments ./main.go:8:6: cannot inline f: marked go:noinline ./main.go:3:6: cannot inline main: non-leaf function ./main.go:10:9: &i escapes to heap ./main.go:10:9: from ~r0 (return) at ./main.go:10:2 ./main.go:9:2: moved to heap: i
  47. 47. 47 $ go tool compile -S main.go ... 0x001d 00029 (main.go:9) LEAQ type.int(SB), AX 0x0024 00036 (main.go:9) MOVQ AX, (SP) 0x0028 00040 (main.go:9) PCDATA $0, $0 0x0028 00040 (main.go:9) CALL runtime.newobject(SB) ...
  48. 48. 48 $ go tool compile -S main.go ... 0x001d 00029 (main.go:9) LEAQ type.int(SB), AX 0x0024 00036 (main.go:9) MOVQ AX, (SP) 0x0028 00040 (main.go:9) PCDATA $0, $0 0x0028 00040 (main.go:9) CALL runtime.newobject(SB) ... func newobject(typ *_type) unsafe.Pointer { return mallocgc(typ.size, typ, true) }
  49. 49. Go Runtime Allocator 49 ● TCMalloc ● Invoking the Allocator ● Go’s Allocator
  50. 50. Go’s Allocator ● Acoplado ao GC e outras partes do runtime ○ Difícil de trocar por outras implementações ● Três tipos de alocação ○ Tiny Allocations (no pointers, size < 16 bytes) ○ Small Allocations (size <= 32 kbytes) ○ Large Allocations 50
  51. 51. Go’s Allocator - Large Allocations 51 1 page 2 pages ... > 255 pages Span Span Span Span Span Spanmheap Busy Spans Span Span Span Antes de alocar, mheap faz o sweep do mesmo número de paginas
  52. 52. Go’s Allocator - Large Allocations 52 1 page 2 pages ... > 255 pages Span Span Span Span Span Span Span Span Span Span Span mheap Free Spans
  53. 53. Go’s Allocator - Large Allocations 53 1 page 2 pages ... > 255 pages Span Span Span Span Span Span mheap Free Spans Span Span Span Span Span mtreap ⇒ randomized binary tree
  54. 54. Go’s Allocator - Large Allocations 54 Depois de alocar, dependendo da quantidade de memória em uso... ● A goroutine pode ter que trabalhar para o GC ● Stop the World
  55. 55. Go’s Allocator - Small Allocations 55 P1 mcache Cada processador lógico (P) tem um cache local (mcache) P2 mcache
  56. 56. Go’s Allocator - Small Allocations 56 P1 P2 mcache mcache Cada mcache mantem um span para cada tamanho (size class) Span Span ... class 1 class 2 Span Span ... class 1 class 2
  57. 57. Go’s Allocator - Small Allocations 57 class bytes/obj bytes/span objects 1 8 8192 1024 2 16 8192 512 3 32 8192 256 4 64 8192 170 ... 65 28672 57344 2 66 32768 32768 1
  58. 58. Go’s Allocator - Small Allocations 58 P1 mcache mcache retorna o endereço de um objeto livre no span Span Span ... class 1 class 2 Span
  59. 59. Go’s Allocator - Small Allocations 59 P1 mcache mcache pede um novo span para o mcentral dessa size class Span Span ... class 1 class 2 Span
  60. 60. Go’s Allocator - Small Allocations 60 P1 mcache Cada mcentral tem duas listas, empty e nonempty spans Span Span ... ... class 1 class 2 mcentral mcentral Span Span Span Span
  61. 61. Go’s Allocator - Small Allocations 61 P1 mcache Span com objetos livres vai ser entregue ao mcache Span ... ... class 1 class 2 mcentral mcentral Span Span Span Span
  62. 62. Go’s Allocator - Small Allocations 62 P1 mcache mcentral vai tentar fazer sweep de spans vazios Span Span ... ... class 1 class 2 mcentral mcentral Span Span If there are no nonempty spans….
  63. 63. Go’s Allocator - Small Allocations 63 Se nada funciona, mcentral vai pedir um novo span para a mheap class 0 mcentral Span Span mheap
  64. 64. Go’s Allocator - Small Allocations 64 mcentral vai dar esse span para a mcache class 0 mcentral Span Span mheapSpan
  65. 65. Go’s Allocator - Tiny Allocations Alocações para objetos sem pointers menores que < 16 bytes The main targets of tiny allocator are small strings and standalone escaping variables. On a json benchmark the allocator reduces number of allocations by ~12% and reduces heap size by ~20%. 65
  66. 66. 66 Go’s Allocator - Tiny Allocations 64 bytes Allocated Free Allocated Free ● Cada P mantem um objeto de 64-bytes que foi alocado de um span ● Cada tiny allocation adiciona um subobjeto ao final do objeto ● O GC não sabe sobre esses subobjetos!
  67. 67. 67 Go’s Allocator - Tiny Allocations Allocated Free mcache P1 ● Pega um novo bloco do mcache ≃ small allocation ● Eventualmente, o GC vai coletar o bloco antigo FreeP1 mcache
  68. 68. Garbage Collector ⇒ Concurrent mark and sweep 68 Go’s Allocator - Sweeping 1. Scan all objects 2. Mark objects that are live 3. Sweep objects that are not live
  69. 69. ● Runtime periodicamente devolve memória ao OS ● Devolve spans que foram garbage collected a mais de 5 minutos ● No Linux, usa a syscall madvise(2) 69 Go’s Allocator - Devolvendo memória ao OS madvise(addr, size, _MADV_DONTNEED)
  70. 70. Analisar alocações ● runtime.ReadMemStats ● pprof ● go tool trace 70
  71. 71. 71 stats := runtime.MemStats{} runtime.ReadMemStats(&stats) type MemStats struct { ... // Heap memory statistics. HeapAlloc uint64 HeapSys uint64 HeapIdle uint64 HeapInuse uint64 HeapReleased uint64 HeapObjects uint64 ... }
  72. 72. Referências 1. http://goog-perftools.sourceforge.net/doc/tcmalloc.html 2. https://www.ardanlabs.com/blog/2017/05/language-mechanics-on-stacks-and-pointers.html 3. https://gabrieletolomei.wordpress.com/miscellanea/operating-systems/in-memory-layout/ 4. Lec 10 | MIT 6.172 Performance Engineering of Software Systems, Fall 2010 5. https://faculty.washington.edu/aragon/pubs/rst89.pdf 6. http://man7.org/linux/man-pages/man2/mmap.2.html 7. http://man7.org/linux/man-pages/man2/madvise.2.html 8. https://github.com/andrestc/linux-prog/blob/master/ch7/malloc.c 72
  73. 73. Obrigado! andrestc.com @andresantostc 73

×