Skip to content

Fix: 큰 게임의 예열이 메모리 한도 근처에서 읽다가 취소하기를 되풀이함 - #184

Merged
DO0OG merged 1 commit into
mainfrom
179-fix-prewarm-memory-boundary-thrash
Nov 13, 2026
Merged

DO0OG merged 1 commit into
mainfrom
179-fix-prewarm-memory-boundary-thrash

Conversation

@DO0OG

@DO0OG DO0OG commented Nov 13, 2026 •

Copy link
Copy Markdown
Owner

Summary

  • 읽을 목록이 큰 게임의 예열이 메모리 한도 근처에서 "HDD 에서 읽다가 취소"를 되풀이하던 문제를 고쳤습니다. 읽은 것은 버리지 않고, 한도에 걸리면 줄여서 마무리하며, 새로 읽을 것이 없으면 디스크를 읽지 않습니다.
  • csharp/src/AsterCache.Service/Prewarm.Run.cs, PrewarmPolicy.cs, Prewarm.Memory.cs: 읽는 도중 메모리 한도에 걸리면 지금 들어가는 범위(가용 − 예비량)를 다시 계산해, 읽은 양이 그 이상이면 그 자리에서 마무리하고 미만이면 그 범위까지 읽고 마무리합니다. 판정은 순수 함수입니다.
  • csharp/src/AsterCache.Service/Prewarm.Supplement.cs: 보충 예열은 범위가 줄어도 이어 읽기 위치를 버리지 않고, 새 범위가 읽은 곳 이하이면 표본도 읽지 않고 끝납니다. 들어가는 범위가 읽은 양보다 max(256 MiB, 5%) 이상 클 때만 시작하며, 못 미치면 <게임>: supplement waits for memory (read X MiB, room for Y MiB) 를 상태가 바뀔 때만 남깁니다. 틈을 메우는 계획은 읽는 양·범위·순서가 그대로이고, 한도에 걸리면 읽은 양을 보수적으로만 기록합니다.
  • csharp/src/AsterCache.Service/Rewarm.cs, Rewarm.Ladder.cs: 보충이 메모리를 기다리는 게임도 재예열 점검에서 표본이 따뜻하면 읽은 범위의 사다리를 만듭니다. 메모리가 늘 모자란 게임이 순서 보호를 받지 못하던 경로를 막은 것입니다.
  • csharp/src/AsterCache.Service/Prewarm.Trigger.cs, Prewarm.Status.cs: 트리거가 고른 게임이 모두 건너뛸 것이면 락을 기다리지 않고 바로 건너뜀을 기록합니다.

알아 둘 점

  • 근거: 설치본 로그에서 보충 예열 취소 93회, 그중 기록에 아무것도 더하지 못한 취소 79회(읽은 양 합계 51,624 MiB). 2026-11-14 04:46 에는 다시 채우는 재예열이 256 MiB 에서 취소되며 읽은 양 기록이 11,388 → 257 MiB 로 줄었고, 뒤이은 보충이 2,209 MiB 를 읽다 취소됐습니다.
  • 메모리 예비량(4,096 MiB)과 캐시 예산은 낮추지 않았습니다. 한도 판정은 묶음(64 MiB 이상) 뒤에 이뤄지므로 한 묶음 정도 넘을 수 있습니다(기존과 같음).
  • 남은 한계: 창을 끝까지 읽은 뒤 더 큰 창이 되면 처음부터 다시 읽습니다(캐시에 있는 부분은 빠르게 지나감). 일반 예열의 전체 경로(순서 바꿈·틈 메우기가 있는 경우)는 기존 처리 그대로이며 로그에서 4건이 해당합니다.
  • 한도로 마무리한 스트림 직후에는 사다리를 만들지 않고, 다음 재예열 점검에서 만듭니다.
  • 설치본에서의 동작은 아직 확인하지 않았습니다.

Test plan

  • dotnet build csharp -c Release -m:1 경고 0, 오류 0
  • dotnet test csharp/tests/AsterCache.Tests -c Release --no-build --filter "Category!=Live" 4,436건 통과 (첫 실행에서 부하로 실패한 2건은 이 변경과 무관한 시험으로, 단독 재실행과 전체 재실행에서 통과)
  • dotnet format csharp --verify-no-changes 통과
  • git diff --check 이상 없음
  • CI build-test 통과: https://github.com/DO0OG/AsterCache/actions/runs/43498046074/job/132136220357

Closes #179

읽을 범위를 "가용 − 256 − 예비량"으로 잡고, 읽는 도중에는 "최종 집합 > 지금 가용 − 예비량"
이면 취소했습니다. 계획 뒤 가용 메모리가 256 MiB 만 줄어도 취소됐고, 취소된 시도가 읽은
것은 대부분 기록에 남지 않아 다음 시도가 처음부터 다시 읽었습니다. 로그에서 보충 예열 취소가
93회였고 그중 79회(읽은 양 합계 51,624 MiB)는 기록에 아무것도 더하지 못했습니다.

- 읽는 도중 메모리 한도에 걸리면 취소하지 않고 지금 들어가는 범위로 줄여 마무리하고 읽은 양을 기록함
- 범위가 줄어도 이어 읽기 위치를 버리지 않고, 새로 읽을 것이 없으면 디스크를 읽지 않음
- 보충 예열은 들어가는 범위가 읽은 양보다 max(256 MiB, 5%) 이상 클 때만 시작함
- 틈을 메우는 계획은 읽는 양과 순서를 그대로 두고, 한도에 걸리면 읽은 양을 보수적으로만 기록함
- 보충이 메모리를 기다리는 게임도 재예열 점검에서 읽은 범위의 사다리를 만듦
- 읽을 게임이 없는 트리거는 락을 기다리지 않고 바로 건너뜀을 기록함
- 메모리 예비량과 캐시 예산은 그대로 둠

Issues #179
@DO0OG
DO0OG merged commit 34b1571 into main Nov 13, 2026
1 check passed
@DO0OG
DO0OG deleted the 179-fix-prewarm-memory-boundary-thrash branch November 13, 2026 20:10
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Fix: 큰 게임의 예열이 메모리 한도 근처에서 읽다가 취소하기를 되풀이함

1 participant