Ruby에서 메모리 할당은 어떻게 작동합니까?
Ruby는 페이지라고 하는 청크로 메모리를 가져오고 여기에 새 개체가 저장됩니다.
그럼...
이 페이지가 가득 차면 더 많은 메모리가 필요합니다.
Ruby는 malloc
을 사용하여 운영 체제에서 더 많은 메모리를 요청합니다. 기능.
이 malloc
기능은 운영 체제 자체의 일부이지만 사용할 수 있는 대체 구현이 있습니다.
이러한 구현 중 하나는 Google의 tcmalloc입니다.
TCmalloc은 Google 성능 도구 제품군의 일부입니다.
이러한 도구를 사용하여 Ruby가 메모리를 할당하는 방법을 정확히 탐색할 수 있습니다.
그리고 LD_PRELOAD
덕분에 환경 변수(Linux에서) 시스템의 malloc
을 대체할 수 있습니다. tcmalloc과 함께 사용합니다.
좋아요 :
LD_PRELOAD="/usr/lib/libtcmalloc.so" ruby -e "puts 123"
그러나 이는 라이브러리만 로드하고 아직 데이터 수집을 활성화하지 않습니다.
어떻게 했는지 봅시다.
프로파일러 활성화
추가 환경 변수(HEAPPROFILE
)로 tcmalloc의 프로파일러를 활성화할 수 있습니다. ).
LD_PRELOAD="/usr/lib/libtcmalloc.so" HEAPPROFILE=/tmp/profile ruby -e "puts 123"
그러면 다음과 같은 출력이 생성됩니다.
Starting tracking the heap 123 Dumping heap profile to /tmp/profile.0001.heap (Exiting, 2 MB in use)
여기에 프로파일러가 활성화되었다는 확인 메시지가 표시됩니다.
그러면 :
- 프로그램의 출력
- 파일 이름(
profile.0001.heap
) - 프로그램에서 사용하는 메모리 양(
2 MB
)
이 파일을 읽으려면 tcmalloc에 포함된 다른 도구가 필요합니다.
pprof --text `which ruby` /tmp/profile.0001.heap | head -10
그러면 다음과 같은 출력이 생성됩니다.
Total: 2.4 MB 1.1 44.7% 44.7% 1.1 44.7% 0x00005570fa4df074 0.7 27.8% 72.5% 0.7 27.8% 0x00005570fa4e0c09 0.4 15.3% 87.8% 0.4 15.3% 0x00005570fa4db460 0.1 5.9% 93.7% 0.1 5.9% 0x00005570fa4df19f 0.1 3.2% 96.9% 0.1 3.2% 0x00005570fa6349a0 0.0 1.4% 98.3% 0.0 1.4% 0x00005570fa589924 0.0 0.3% 98.6% 0.0 0.3% 0x00005570fa59c4f2 0.0 0.3% 98.8% 0.0 0.3% 0x00005570fa4db48a 0.0 0.2% 99.0% 0.0 0.2% 0x00005570fa4dbaa5 0.0 0.2% 99.1% 0.0 0.2% _dl_new_object
글쎄, 그것은 단지 많은 메모리 주소입니다! 함수 이름을 보려면 디버깅 기호가 있는 Ruby 버전이 필요합니다.
이 결과를 얻을 수 있습니다. :
Using local file ruby. Using local file /tmp/profile.0001.heap. Total: 2.9 MB 1.0 36.2% 36.2% 1.0 36.2% objspace_xmalloc0 0.7 26.1% 62.4% 0.7 26.1% aligned_malloc 0.5 18.8% 81.1% 0.5 18.8% objspace_xcalloc 0.3 9.9% 91.0% 0.3 9.9% stack_chunk_alloc 0.1 3.7% 94.7% 0.1 3.7% objspace_xrealloc 0.1 2.7% 97.4% 0.1 2.7% Init_Method 0.0 1.3% 98.7% 0.0 1.7% onig_new_with_source 0.0 0.4% 99.2% 0.8 26.6% heap_page_allocate 0.0 0.2% 99.4% 0.0 0.2% add_bitset
여기에서 볼 수 있는 것은 MRI의 기능에 의해 할당된 메모리의 양입니다.
aligned_malloc
Ruby 객체, stack_chunk_alloc
에 새 페이지를 할당하는 데 사용되는 함수입니다. 마킹 단계에서 GC 자체에서 사용되며 objspace_xmalloc0
/ objspace_xcalloc
RVALUE
에 맞지 않는 문자열, 배열 및 기타 데이터를 위한 공간 할당 구조체.
지금:
TCmalloc은 Ruby 객체에 대해 아무 것도 모르고, 요청되는 메모리의 양을 찾기 위해 malloc, calloc 및 realloc에 대한 호출을 추적하는 것만 합니다.
Ruby 수준에서 힙 덤프를 얻으려면 ObjectSpace.dump_all
을 사용할 수 있습니다. . 이렇게 하면 애플리케이션의 모든 라이브 개체와 메모리 크기가 포함된 JSON 파일이 제공됩니다.
하지만 tcmalloc
메모리를 요청하는 모든 C 함수의 시각화임을 보여줄 수 있습니다.
pprof --web `which ruby` /tmp/profile.0001.heap
그러면 다음과 같은 SVG 파일이 있는 Chrome 또는 Firefox가 열립니다.
TCmalloc은 이 멋진 프로파일링 기능을 제공할 뿐만 아니라 이를 사용하여 애플리케이션의 성능을 4-9%까지 높일 수 있습니다! jemalloc
을(를) 사용해 볼 수도 있습니다. , 이는 또 다른 malloc
프로파일러도 포함하는 구현
요약
gperftools(Google 성능 도구)를 사용하여 Ruby 인터프리터의 메모리 사용량을 시각화하고 분석하는 방법을 배웠습니다.
읽어 주셔서 감사합니다! 🙂