aboutsummaryrefslogtreecommitdiffstats
path: root/docs/research/036-gtk-memory-boundary.md
diff options
context:
space:
mode:
Diffstat (limited to 'docs/research/036-gtk-memory-boundary.md')
-rw-r--r--docs/research/036-gtk-memory-boundary.md89
1 files changed, 89 insertions, 0 deletions
diff --git a/docs/research/036-gtk-memory-boundary.md b/docs/research/036-gtk-memory-boundary.md
new file mode 100644
index 0000000..d90246d
--- /dev/null
+++ b/docs/research/036-gtk-memory-boundary.md
@@ -0,0 +1,89 @@
+# 036 — 선택형 문서 창의 메모리 경계
+
+2026-09-24. 사용자가 원하는 것은 작은 **애플리케이션 런타임**이다. GTK 창의
+프로세스 비용을 코어의 비용처럼 취급하거나, 작은 압축 묶음만으로 메모리 목표를
+달성했다고 말할 수 없다. 여기서는 [035](035-native-multi-document-window.md)의
+1 MiB 문서 반복 전환에서 나타난 증가를 분리했다. 앱 기능을 추가하지 않았다.
+
+Linux AArch64에서 실제 GTK 창을 Xvfb 아래 띄우고, 1 MiB 문서 두 개를
+64회 열었다. 8회마다 `/proc/<pid>/status` RSS와 `smaps`의 영역별 RSS를
+기록했다. 각각의 대조 실험은 같은 문서 앱의 저장·편집·충돌·정의 적용
+시나리오도 통과했다. RSS는 단일 실행의 관찰값이며, 실험 간 절댓값 차이를
+성능 순위로 해석하지 않는다.
+
+| 조건 | 8회 후 RSS | 64회 후 RSS | 힙 RSS 증가 |
+|---|---:|---:|---:|
+| 두 키, 서로 다른 1 MiB 본문 | 47,472 KiB | 58,896 KiB | 11,296 KiB |
+| 같은 키 다시 열기 | 47,056 KiB | 47,072 KiB | 16 KiB |
+| 두 키, 동일한 본문 | 47,216 KiB | 59,680 KiB | 12,464 KiB |
+| 두 키, 1 MiB 전환 시 텍스트 뷰 갱신만 생략한 **진단 빌드** | 47,216 KiB | 47,216 KiB | 0 KiB |
+| 두 키, 문서 버퍼 실행 취소 기능 비활성화 | 47,440 KiB | 59,008 KiB | 11,440 KiB |
+| 두 키, 줄바꿈 비활성화 | 45,888 KiB | 57,440 KiB | 11,424 KiB |
+
+원자료는 순서대로
+[기본](../../prototypes/connections/results/2026-09-24-window-memory-analysis/smaps.json),
+[같은 키](../../prototypes/connections/results/2026-09-24-window-memory-analysis/same-key.json),
+[같은 본문](../../prototypes/connections/results/2026-09-24-window-memory-analysis/same-body.json),
+[텍스트 갱신 생략](../../prototypes/connections/results/2026-09-24-window-memory-analysis/skip-text.json),
+[실행 취소 비활성화](../../prototypes/connections/results/2026-09-24-window-memory-analysis/no-document-undo.json),
+[줄바꿈 비활성화](../../prototypes/connections/results/2026-09-24-window-memory-analysis/no-wrap.json)에 있다.
+텍스트 갱신 생략 빌드는 **문서를 제대로 보여주지 않으므로 제품 수정안이 아니다.**
+키·버전·본문 복사·정의·저장 경로는 그대로 실행하고, 1 MiB의 다른 키를 열 때
+`gtk_text_buffer_set_text()` 호출만 건너뛰어 원인 경계를 분리했다.
+
+`mallinfo2`를 추가한 별도 진단 빌드에서는 glibc 할당기의 `uordblks`가
+8회 후 10,897,312 B에서 64회 후 23,427,504 B로 증가했다
+([원자료](../../prototypes/connections/results/2026-09-24-window-memory-analysis/mallinfo.json)).
+따라서 관찰된 증가는 단순히 해제된 블록을 할당기가 보유하는 현상만으로
+설명되지 않는다. 반면 이 수치는 어떤 GTK 객체가 데이터를 소유하는지,
+그 객체가 언제 반환되는지까지 밝히지 않는다. 종료 후 누수량과 실행 중
+힙 사용량도 같은 지표가 아니므로, 이 결과만으로 누수를 단정하지 않는다.
+
+GTK 문서는 [`GtkTextBuffer.set_text()`가 이전 내용을 지우고 새 내용을 넣으며
+실행 취소 불가능한 작업으로 표시된다](https://docs.gtk.org/gtk4/method.TextBuffer.set_text.html)고
+설명한다. 실행 취소와 줄바꿈을 각각 꺼도 증가량이 유지된 점과 함께 보면,
+현재 위치는 **GTK 텍스트 교체 경계**다. 이전 버퍼를 새 버퍼로 바꾸는 실험도
+[035의 원자료](../../prototypes/connections/results/2026-09-24-multi-document-window/switch-memory-fresh-buffer.json)에서
+효과가 없었다. 특정 GTK 내부 캐시나 누수라는 결론은 내리지 않는다.
+
+재현 가능한 제품 빌드의 기준 경로는
+`make -C prototypes/connections window editor` 다음
+`xvfb-run -a python3 prototypes/connections/check_window.py --build prototypes/connections/build --program prototypes/connections/examples/editor.pure --switch-rounds 64 --diagnose-maps`다.
+진단 변형은 제품 코드에서 제거했다. 텍스트 갱신 생략 변형은
+`open_document_key()`의 `gtk_text_buffer_set_text()` 앞에
+`if (!(strcmp(key, e->key) != 0 && e->baseline_size >= 1000000))`를
+놓되, 키 변경 전의 값을 비교해야 한다. 다른 변형은 창 생성 시 문서 버퍼에
+`gtk_text_buffer_set_enable_undo(buffer, FALSE)`를 호출하거나 문서 뷰의
+`GTK_WRAP_WORD_CHAR`를 `GTK_WRAP_NONE`으로 바꾼 것이다. `mallinfo2`
+변형은 문서 열기 완료 직후 할당기 통계를 기록했다.
+
+현재 비용 경계는 분명하다. 기본 CLI의 1 MiB 작업에는
+[4 MiB 최대 RSS 검사](../../prototypes/connections/check_micro_memory.py)가 있고,
+GTK·TLS는 기본 실행물에 링크되지 않는다. 선택형 GTK 창은 시작부터 약
+44 MiB RSS를 쓰고 위 반복 전환에서는 더 증가한다. 따라서 **이 창을
+마이크로 메모리 프로필이라고 부르지 않는다.** 선택형 창의 기능 검증은
+유효하지만 저메모리 UI를 증명하지 않는다. 큰 앱·서비스로 확장하기 전에
+실행 코어와 어댑터의 비용을 계속 따로 공개하고, UI에는 실제 화면·입력·
+편집 기능을 유지한 상태에서 전환 후 메모리가 안정되는 구현이 필요하다.
+
+진단 코드를 제거한 최종 창도 [64회 전환 기능·RSS 검사](../../prototypes/connections/results/2026-09-24-window-memory-analysis/final-native-window.json)를
+통과했고, RSS는 8회 후 47,216 KiB에서 64회 후 58,528 KiB로 증가했다.
+같은 상태의 `make check-release check-window-profile`에서는 코어 `text`
+5,932 B, 기본 CLI의 1 MiB 편집 피크 RSS 2,080 KiB, 선택형 GTK 창의
+`text` 49,946 B가 각 회귀 상한을 통과했다. GTK 창의 코드 섹션 통과는
+전체 GTK 프로세스의 메모리 통과를 뜻하지 않는다. 이 결과를 반영해 다음
+GUI 기능을 추가하기 전에 창 메모리의 경계 또는 더 작은 네이티브 UI 어댑터를
+검증해야 한다.
+
+추가 대조에서 마지막 전환 후 10초간 창을 유휴 상태로 두어도 RSS는
+59,328→59,456 KiB로 줄지 않았다
+([원자료](../../prototypes/connections/results/2026-09-24-window-memory-analysis/settled-final.json)).
+같은 1 MiB를 80 B 줄 대신 4,096 B 줄로 구성하면 8→64회 힙 RSS 증가가
+11,296 KiB에서 17,792 KiB로 오히려 커져, 단순한 **줄당 고정 비용** 가설도
+맞지 않았다
+([원자료](../../prototypes/connections/results/2026-09-24-window-memory-analysis/line-width-4096.json)).
+전환마다 문서 `GtkTextView` 전체를 파괴·재생성한 진단 빌드 역시 힙 RSS가
+14,416→25,968 KiB로 증가했다
+([원자료](../../prototypes/connections/results/2026-09-24-window-memory-analysis/replace-view.json)).
+이 세 실험은 GTK 내부 소유자를 특정하지 않는다. 뷰를 매번 재생성하는
+제품 코드는 채택하지 않았고, 작은 코어의 실행 모델 작업에 우선순위를 둔다.