가비지 컬렉션(Garbage Collection)
가비지 컬렉션(Garbage Collection)
Racket은 메모리를 자동으로 관리하고, 각 가비지 컬렉션의 세부 정보를 로그로 남겨요. 환경 변수로 컬렉션을 비활성화하거나 증분 모드를 요청할 수도 있습니다.
출처: Racket Reference
본문
가비지 컬렉션을 비활성화하려면 Racket이 시작하기 전에 PLTDISABLEGC 환경 변수를 (어떤 값이든) 설정하세요. Racket의 3m 구현체에서 항상 증분 모드(incremental mode)를 요청하려면 PLT_INCREMENTAL_GC 환경 변수를 1, y, Y로 시작하는 값으로 설정하세요. 하지만 주기적인 작업이 있는 프로그램에서 (collect-garbage 'incremental)을 호출하는 것이 증분 모드를 요청하는 더 나은 메커니즘입니다. (모든 Racket 구현체에서) 증분 모드 요청을 비활성화하려면 PLT_INCREMENTAL_GC 환경 변수를 0, n, N으로 시작하는 값으로 설정하세요.
각 가비지 컬렉션은 'debug 수준에서 'GC 토픽으로 메시지(Logging 참고)를 로깅합니다. Racket의 CS와 3m 구현체에서 "major" 컬렉션은 'debug 수준에서 'GC:major 토픽으로도 로깅됩니다. Racket의 CS와 3m 구현체에서 메시지의 데이터 부분은 다음과 같은 10개 필드를 가진 gc-info prefab 구조체 타입의 인스턴스입니다. 다만 미래 버전의 Racket은 추가 필드를 가진 gc-info prefab 구조체를 사용할 수 있습니다:
(struct gc-info (mode pre-amount pre-admin-amount code-amount
post-amount post-admin-amount
start-process-time end-process-time
start-time end-time)
#:prefab)
mode 필드는 'major, 'minor, 'incremental 심볼입니다. 'major는 모든 메모리를 검사하는 컬렉션을, 'minor는 대부분 최근 할당만 검사하는 컬렉션을, 'incremental은 다음 major 컬렉션을 향해 추가 작업을 수행하는 minor 컬렉션을 나타냅니다.
package base의 6.3.0.7 버전에서 변경: 첫 필드가 불리언('major면 #t, 'minor면 #f)에서 mode 심볼로 변경되었습니다.
pre-amount 필드는 가비지 컬렉션이 시작된 시점의 place-로컬 메모리 사용량(즉 자식 place의 메모리 사용량은 세지 않음)을 바이트 단위로 보고합니다. make-phantom-bytes로 등록된 추가 바이트가 포함됩니다.
pre-admin-amount는 더 큰 숫자로, 매핑되었지만 현재 사용되지 않는 메모리 페이지의 공간 같은 가비지 컬렉터의 오버헤드에 대한 메모리 사용량을 포함합니다.
code-amount 필드는 생성된 네이티브 코드에 대한 추가 메모리 사용량을 보고합니다(가비지 컬렉션 직전과 직후에 같습니다, finalization으로 해제되기 때문입니다).
post-amount와 post-admin-amount 필드는 pre-amount와 pre-admin-amount에 대응하지만 가비지 컬렉션 이후의 값입니다. 일반적인 설정에서 post-amount와 pre-amount의 차이는 post-admin-amount에 기여합니다. 회수된 페이지가 다시 필요할 것이라는 기대와 함께 예비로 남는 경향이 있기 때문입니다(하지만 페이지가 필요한 일 없이 여러 컬렉션이 지나가면 페이지는 해제됩니다).
start-process-time와 end-process-time 필드는 가비지 컬렉션 시작과 끝에서의 프로세서 시간(current-process-milliseconds의 의미로)을 보고합니다. 시간들의 차이는 컬렉션이 소비한 프로세서 시간입니다.
start-time와 end-time 필드는 가비지 컬렉션 시작과 끝에서의 실시간(current-inexact-milliseconds의 의미로)을 보고합니다. 시간들의 차이는 가비지 컬렉션이 소비한 실시간입니다.
로깅된 메시지 텍스트의 형식은 변경될 수 있습니다. 현재는 place와 컬렉션 모드를 나타내는 접두사 뒤에 텍스트가 다음 형식을 갖습니다:
‹used›(‹admin›)[‹code›]; free ‹reclaimed›(‹adjust›) ‹elapsed› @ ‹timestamp›
‹used›: 가비지 컬렉션 직전에 사용 중인 수집 가능한(collectable) 메모리‹admin›: 수집 가능한 메모리를 관리하는 데 사용된 추가 메모리‹code›: 생성된 기계어 코드에 사용된 추가 메모리‹reclaimed›: 가비지 컬렉션이 회수한 수집 가능한 메모리‹adjust›: 관리 메모리의 변화에 대한 부정(-‹reclaimed›)‹elapsed›: 가비지 컬렉션을 수행하는 데 사용된 프로세서 시간‹timestamp›: 가비지 컬렉션 시작 이후의 프로세서 시간
package base의 6.3.0.7 버전에서 변경: PLT_INCREMENTAL_GC가 추가되었습니다.
7.6.0.9 버전에서 변경: 'GC:major 토픽에 대한 major 컬렉션 로깅이 추가되었습니다.
collect-garbage
procedure
(collect-garbage [request]) → void?
request : (or/c 'major 'minor 'incremental) = 'major
request에 따라 즉시 가비지 컬렉션을 요청하거나 가비지 컬렉션 모드를 요청합니다:
-
'major— 모든 메모리를 검사하는 "major" 컬렉션을 강제합니다. 컬렉터가 도달 불가능함을 증명할 수 없어서 몇몇 실질적으로 도달 불가능한 데이터가 수집되지 않고 남을 수 있습니다.collect-garbage프로시저의 이 모드는 컬렉션의 시점에 대해 어느 정도 제어를 제공하지만, 이 프로시저가 절대 호출되지 않아도 가비지는 당연히 수집됩니다—가비지 컬렉션이PLTDISABLEGC를 설정해 비활성화되지 않는 한. -
'minor— 대부분 최근 할당만 검사하는 "minor" 컬렉션을 요청합니다. minor 컬렉션이 지원되지 않거나(예:(system-type 'gc)가'cgc를 반환할 때) 다음 컬렉션이 major 컬렉션이어야 한다면 컬렉션이 수행되지 않습니다. 더 일반적으로,(collect-garbage 'minor)가 촉발하는 minor 컬렉션은 major 컬렉션을 그렇지 않을 때보다 더 일찍 일어나게 하지 않습니다. -
'incremental— 즉시 컬렉션을 요청하지 않지만, major 컬렉션을 피하기 위해 앞으로 추가 노력을 요청합니다. major 컬렉션의 작업을 증분적으로 수행하기 위해 minor 컬렉션마다 더 많은 작업이 필요하더라도 그렇습니다. 이 증분 모드 요청은 다음 major 컬렉션에서 만료됩니다.
증분 모드의 의도는 major 컬렉션으로 인한 일시 정지 시간을 크게 줄이는 것입니다. 하지만 증분 모드는 더 긴 minor-컬렉션 시간과 더 높은 메모리 사용을 의미할 수 있습니다. 현재 증분 모드는 CS와 3m Racket 구현체에서만 의미가 있고, 다른 Racket 구현체에서는 효과가 없습니다.
시작 시 PLT_INCREMENTAL_GC 환경 변수의 값이 0, n, N으로 시작하면 증분 모드 요청은 무시됩니다.
package base의 6.3 버전에서 변경: request 인자가 추가되었습니다.
6.3.0.2 버전에서 변경: 'incremental 모드가 추가되었습니다.
7.7.0.4 버전에서 변경: Racket CS에 'incremental 효과가 추가되었습니다.
current-memory-use
procedure
(current-memory-use [mode]) → exact-nonnegative-integer?
mode : (or/c #f 'cumulative 'peak custodian?) = #f
메모리 사용에 대한 정보를 반환합니다:
mode가#f(기본값)이면 결과는 어떤 custodian에서든 도달 가능한 바이트 수의 추정치입니다.mode가'cumulative이면 시작 이후 할당된 총 바이트 수의 추정치를 반환합니다. 가비지 컬렉션이 그 이후 회수한 바이트도 포함합니다.mode가'peak이면 시작 이후 Racket 프로세스에서 어떤 가비지 컬렉션 직전의 할당된 최대 바이트 수를 반환합니다.mode가 custodian이면mode에서 도달 가능한 데이터가 차지하는 메모리 바이트 수의 추정치를 반환합니다. 이 추정치는 마지막 가비지 컬렉션으로 계산되며, 컬렉션이 없었다면(또는 주어진 custodian이 생성된 후 컬렉션이 없었다면) 0일 수 있습니다.current-memory-use함수는 스스로 컬렉션을 수행하지는 않습니다. 호출 전에 컬렉션을 수행하면 일반적으로 결과가 감소합니다(아직 컬렉션이 없었다면 0에서 증가).
Racket이 메모리 회계(memory accounting) 지원 없이 컴파일되면, 개별 custodian에 대한 추정치는 mode가 #f일 때와 같습니다(즉 모든 메모리). custodian-memory-accounting-available?도 함께 보세요.
vector-set-performance-stats!도 함께 보세요.
package base의 6.6.0.3 버전에서 변경: 'cumulative 모드가 추가되었습니다.
8.10.0.3 버전에서 변경: 'peak 모드가 추가되었습니다.
dump-memory-stats
procedure
(dump-memory-stats v ...) → any
v : any/c
메모리 사용에 대한 정보를 저수준 오류 포트(low-level error port)나 콘솔에 덤프합니다.
v 인자의 다양한 조합이 덤프의 정보를 제어할 수 있습니다. 사용 가능한 정보는 Racket 빌드에 따라 다릅니다. 특정 빌드에서 추가 정보를 제공하는지 덤프의 끝을 확인해 보세요. 그렇지 않으면 모든 v는 무시됩니다.