Computer >> 컴퓨터 >  >> 프로그램 작성 >> Ruby

Ruby에서 메모리 누수를 만드는 방법

메모리 누수를 찾는 방법에 대한 몇 가지 기사가 있습니다.

그러나 하나를 만드는 것은 어떻습니까?

Ruby에서 메모리 누수가 어떻게 보이는지 알 수 있도록 흥미로운 연습이 될 것이라고 생각합니다.

몇 가지 예를 살펴보겠습니다.

간단한 누출

배열에 새 개체를 추가하기만 하면 메모리 누수가 발생할 수 있습니다.

좋아요 :

a = []
b = {}

loop {
  sleep(1)

  10_000.times { a << "abc" }

  puts GC.stat(b)[:heap_live_slots]
}

이것은 매초 10k 문자열을 생성하고 개체 수를 인쇄합니다:

285051
295052
305053
315054
325055
335056
345057
355058

GC가 이러한 문자열을 수집할 수 없으므로 포함하는 배열(a ).

a인 경우 GC가 이러한 모든 "abc"를 수집할 수 있는 범위를 벗어납니다. 문자열. a를 설정하여 위의 예에서 이를 테스트할 수 있습니다. nil로 설정한 다음 GC.start 실행 .

여기에서 라이브 예제를 찾을 수 있습니다. run을 클릭하기만 하면 됩니다. 결과를 확인하세요.

C 확장자 누출

Ruby에서 객체를 생성할 때 GC는 사용 중인 메모리 양을 추적하지만 C 확장을 사용할 때 Ruby는 어떤 일이 발생하는지 제어할 수 없습니다.

다음과 같이 C 확장을 만드는 경우:

#include <ruby.h>
#include "extconf.h"

void *ptr;

void Init_extension()
{
  allocate_memory();
}

void allocate_memory() {
  for(int i = 0; i < 10000; i++) {
   ptr = malloc(1000);
  }
}

allocate_memory() 함수는 malloc를 사용하기 때문에 메모리 누수가 발생합니다. &free라고 부르지 않습니다. 그 기억을 해제합니다.

여기에서 볼 수 있듯이:

`ps -o rss -p #{$$}`.lines.last
# "49036"

require './extension'

`ps -o rss -p #{$$}`.lines.last
# "89512"

이러한 종류의 누수는 힙 덤프나 GC.stat에 표시되지 않습니다. 하지만 메모리 사용량이 증가하는 것을 볼 수 있습니다.

요약

이제 메모리 누수가 어떻게 생겼는지 알았습니다. 이 문제가 발생하면 더 빨리 찾는 데 도움이 될 것입니다. Btw Ruby 2.4.1에는 알려진 메모리 누수가 있으므로 이 특정 버전을 사용하는 경우 업그레이드하는 것이 좋습니다.

질문, 피드백 또는 흥미로운 메모리 누수 디버깅 스토리가 있습니까? 아래에 댓글을 남겨주세요 🙂

읽어주셔서 감사합니다!