Home GC DATAS (Dynamic Adaptation To Application Sizes, 동적 힙 갯수 조절)
Post
Cancel

GC DATAS (Dynamic Adaptation To Application Sizes, 동적 힙 갯수 조절)

DATAS (Dynamic Adaptation To Application Sizes, 동적 힙 갯수 조절)

힙 메모리 사용량에 따라 힙 갯수를 줄이고 늘릴 수 있는 기능.

.NET8 에서 추가된 기능. 내용이 길어져서 별도 포스트로 나누었다.

원본은 이 포스트에서 확인가능.

디테일한 내용은 추후 포스팅을 통해 설명할 예정이며 지금도 개발중에 있기때문에 내용이 바뀔 수도 있다고 한다. (maoni 선생님도 원래는 작업이 완료되면 정리해서 하나의 포스트로 올리려 했는데 닷넷 사용자들이 하도 요청해서 미리 썼다고..)


서론

CLR은 .NET8 이전에도 이미 객체 생존 비율, 실제 메모리 부하 등을 따져가며 동적으로 힙을 관리하고 있지만 다음과 같은 문제가 있다.

  1. GCHeapCount 값을 통해 초기에 힙 갯수를 설정할 수 있다. 하지만 런타임에 수정이 불가능.
  2. .NET 6에서는 Allocation Budget(객체 메모리 할당을 위해 여유분을 잡아두는 양) 조절을 통해 힙 메모리를 조절하였지만, GC가 트리거 되기전까지 이미 줄인 budget은 변경이 불가능하고, 힙 갯수만큼 예산도 커져서 적절하게 조절하기 어렵다.

이런 한계를 극복하기 위해 더 다양한 조건에서 적응할 수 있는 동적 힙옵션(DATAS) 기능을 추가하게 되었고, DATAS는 힙의 갯수 조절ㅡ Allocation Budget, 메모리 할당 policy에 대한 세밀한 조정을 할 수 있게 되었다.


내부 구현

DATAS는 메모리 사용량이 가장 피크를 치는 경우(= Application Size)를 기준으로 메모리를 적절히 조절하는 것이 목표다.

DATAS 옵션이 켜져있으면 힙 1개에서 출발하여 커지고 작아진다. (CLR팀은 옵션을 키면 사용자가 힙사이즈를 특정할 필요가 없기를 원했음)

3번의 GC를 수행할 때마다 Throughput cost, Space cost 두 가지를 값을 측정하여 힙 갯수 조정에 사용한다.

Throughput cost

처리량에 대한 비용은 힙 대기 시간을 통해 계산한다.

대기 시간이 많다는 것은 GC를 위해 힙 할당을 대기하고 있는 시간이 길어지고 있고 힙 할당을 위한 처리량이 많다는 뜻이므로, 대기 시간을 통해 처리량 비용을 계산한다.

여기서 Full GC는 상대적으로 cost가 너무 커질수 있기 때문에 평균을 계산하기 어렵고, Background GC 또한 GC가 진행되는 시간이 부하와는 연관이 없기 때문에 식에서 제외한다.

1
2
3
throughput_cost = (total_SOH_wait time + total_UOH_wait time) / num_of_heaps + 
                   GC duration
throughput_cost_percentage = throughput_cost / elapsed_time_since_the_last_GC

Space cost

공간에 대한 비용은 전체 힙 사이즈에서 사용자 힙 할당 비율을 통해 계산한다.

사용자가 얼마나 메모리를 많이 사용하는지, 얼마나 GC가 자주 발생하는지 비율을 체크하기 위한 비용. 메모리를 많이 사용하면 GC는 그만큼 적게 실행되므로.

사용자의 객체 할당 대부분은 Gen0 부터 시작하므로, Gen 0의 Allocation Budget 최소값을 통해 얼마나 할당을 많이하는지 체크하고 있으나, 힙 사이즈가 커지면 Space cost는 상대적으로 너무 작은 값을 가지게 되므로 유용하지 않아서 추후 변경 예정.

1
size_of_an_extra_heap / total_heap_size

cost 활용방법

Space cost를 사용해서 Throught cost를 많이 절약할 수 있는 경우, 반대로 Throught cost를 사용하여 Space cost를 절약할 수 있는 경우를 따져가며 힙 갯수를 조절한다.

cost는 매우 높음(10% 이상), 상당히 높음(5~10%)에 따라 단계적으로 조정한다.

CLR팀에서는 힙 갯수의 변경이 너무 자주 일어나지 않도록 힙 갯수의 하향 조정은 되도록 하지않고 있다고 하며, 퍼센트 비율 또한 사용자가 조절할 수 있도록 작업할 예정이라고 한다.


동적 GC(DATAS)에 대한 고찰

  • 동적 GC가 특정 수치에 대한 최적화를 위한 작업이 아닌 일반적으로 향상된 성능을 가지도록 노력하고 있다.

  • GC가 측정해야되는 항목이 많아지면서 GC 자체에 많은 부담이 되고 있는데 이를 지속적으로 개선하고 있다.

  • AoT(Ahead of Time, IL 코드를 컴파일시간에 native code로 컴파일 해주는) 테스트는 제외하였음, 추후 지원 예정.


사용 방법

동적 힙 옵션은 default 값으로 꺼져있으므로 다음과 같은 방식으로 켤수 있다.

  • (Server GC에서만 사용이 가능하다. Workstatcion GC는 힙이 하나이므로 당연히..)

  • (이후 릴리즈 버전에서 자동으로 키도록 변경할 예정이라고 합니다)

  1. Runtimeconfig.json에서 다음과 같이 설정
1
2
3
4
“configProperties”: {
  "System.GC.Server": true,
  "System.GC.DynamicAdaptationMode": 1
}
  1. msbuild 프로퍼티를 통해 설정
1
2
3
4
<PropertyGroup>
  <ServerGarbageCollection>true</ServerGarbageCollection>
  <GarbageCollectionAdaptationMode>1</GarbageCollectionAdaptationMode>
</PropertyGroup>
  1. 환경 변수를 통해 설정
1
2
set DOTNET_gcServer=1
set DOTNET_GCDynamicAdaptationMode=1

This post is licensed under CC BY 4.0 by the author.

.NET 8 변경점

PGO (Profile Guided Optimization, 프로필 기반 최적화)