IT story

gc ()가 메모리를 해제하지 않는 이유는 무엇입니까?

hot-time 2020. 12. 31. 22:55
반응형

gc ()가 메모리를 해제하지 않는 이유는 무엇입니까?


나는에 대한 시뮬레이션을 실행 윈도우 64 비트 - 컴퓨터64기가바이트 RAM을 . 메모리 사용량이 55 %에 도달 하고 시뮬레이션 실행이 완료된 후 작업 공간에있는 모든 개체를 제거 rm(list=ls())하고 double gc().

나는 이것이 다음 시뮬레이션 실행을 위해 충분한 메모리를 확보 할 것이라고 생각했지만 실제로 메모리 사용량 은 단지 1 % 만 감소합니다 . 많은 다른 포럼을 참조하면 만족스러운 설명을 찾을 수 없었고 다음과 같은 모호한 의견 만 찾을 수있었습니다.

"운영 체제에 따라 비워진 메모리는 운영 체제로 반환되지 않고 프로세스 공간에 보관 될 수 있습니다."

다음에 대한 정보를 찾고 싶습니다.

  • 1) 어떤 OS와 어떤 조건에서 해제 된 메모리가 OS로 반환되지 않는지
  • 2) R을 닫고 다음 시뮬레이션 실행을 위해 다시 시작하는 것 외에 다른 해결책이 있다면?

메모리 사용량을 어떻게 확인합니까? 일반적으로 가상 머신은 데이터를 저장하는 데 사용하는 일부 메모리 청크를 할당합니다. 할당 된 일부는 사용되지 않고 무료로 표시 될 수 있습니다. GC가하는 일은 다른 곳에서 참조되지 않는 데이터를 발견하고 해당 메모리 청크를 사용되지 않음으로 표시하는 것입니다. 이것은이 메모리가 OS에 릴리스된다는 것을 의미하지 않습니다. 여전히 VM 관점에서 추가 계산에 사용할 수있는 더 많은 여유 메모리가 있습니다.

다른 사람들이 물었 듯이 메모리 부족 오류가 발생 했습니까? 그렇지 않다면 걱정할 것이 없습니다.

편집 : 메모리 할당과 가비지 컬렉션은 R. 어떻게 작동하는지 충분해야 이해하기

첫 번째 문서에서 :

때때로 사용하지 않는 페이지를 운영 체제로 다시 릴리스하려고 시도합니다. 페이지가 해제되면 R_MaxKeepFrac에 각 클래스에 할당 된 노드 수를 곱한 것과 동일한 사용 가능한 노드 수가 유지됩니다. 이 요구 사항을 충족하는 데 필요하지 않은 페이지가 릴리스됩니다. 페이지를 릴리스하려는 시도는 모든 R_PageReleaseFreq 레벨 1 또는 레벨 2 콜렉션에서 이루어집니다.

EDIT2 :

사용 된 메모리를 보려면 verbose를 TRUE로 설정하여 gc ()를 실행 해보십시오.

gc(verbose=T)

메모리에 10,000,000 개의 정수 배열이있는 결과는 다음과 같습니다.

Garbage collection 9 = 1+0+8 (level 2) ... 
10.7 Mbytes of cons cells used (49%)
40.6 Mbytes of vectors used (72%)
          used (Mb) gc trigger (Mb) max used (Mb)
Ncells  198838 10.7     407500 21.8   350000 18.7
Vcells 5311050 40.6    7421749 56.7  5311504 40.6

그리고 여기에 대한 참조를 폐기 한 후 :

Garbage collection 10 = 1+0+9 (level 2) ... 
10.7 Mbytes of cons cells used (49%)
2.4 Mbytes of vectors used (5%)
         used (Mb) gc trigger (Mb) max used (Mb)
Ncells 198821 10.7     407500 21.8   350000 18.7
Vcells 310987  2.4    5937399 45.3  5311504 40.6

보시다시피 Vcells에서 사용하는 메모리는 40.6Mb에서 2.4Mb로 떨어졌습니다.


R가비지 컬렉터는 다음의 불완전 (그리) 미묘한 방법 : 그것은 않습니다 하지 객체 (즉, 그렇지 않은 이동 컴팩트 때문에이와 상호 작용하는 방식의 메모리) C라이브러리를. (일부 다른 언어 / 구현도이 고통,하지만 다른 사람 도와 상호 작용하는 데에도 불구하고이 C하는 가지고 관리 압축 세대 GC 않습니다 하지 이 문제로 고통을).

이것은 당신이 버려지는 메모리의 작은 청크를 번갈아 가며 더 영구적 인 객체를 위해 더 큰 청크를 할당한다면 (이것은 문자열 / 정규식 처리를 할 때 일반적인 상황입니다), 당신의 메모리는 조각화 되고 가비지 수집기는 아무것도 할 수 없습니다. it : 메모리가 해제되지만 여유 청크가 너무 짧기 때문에 재사용 할 수 없습니다.

문제를 해결하는 유일한 방법은 원하는 객체를 저장하고 다시 시작한 R다음 객체를 다시로드하는 것입니다.

당신이하고 있기 때문에 rm(list=ls())다시 시작 - 즉, 당신은 그래서, 당신의 경우, 솔루션은 피하고 싶은 정확히 무엇이며, 재 장전 아무것도 저장하지 않아도, 물건을 필요하지 않습니다 R.

추신. 가비지 수집은 매우 사소한 주제입니다. 예를 들어 Ruby는 20 년 동안 5 가지 (!) 개의 서로 다른 GC 알고리즘을 사용했습니다 . 썬 / 오라클IBM각자의 GC 구현에 많은 프로그래머 년보냈기 때문에 Java GC는 좋지 않습니다 . 반면에 R과 Python은 GC가 좋지 않습니다. 필요한 인력을 투자 할 사람이 없기 때문에 꽤 인기가 있습니다. 그것은 당신에게 더 나쁜 것입니다.

PPS. 관련 : R :`strsplit`을 사용하여 메모리 부족

참조 URL : https://stackoverflow.com/questions/14580233/why-does-gc-not-free-memory

반응형