store.js 파일에 메모리 누수가 있는 것 같습니다. 사용자가 다른 토픽을 탐색할 때마다 각 RESTful 요청마다 _identityMap이 빠르게 증가하는 것처럼 보입니다. 적절한 정리 로직이 없으면 이 맵은 큰 JS 힙에서 메모리를 소진하게 됩니다.
store.js에 FIFO 알고리즘을 사용하여 가장 오래된 맵을 제거하는 pruneMap 함수를 추가하는 것만으로도 충분할까요?
3개의 좋아요
이 문제에 대해 더 자세히 알려 주실 수 있나요?
이를 뒷받침할 수 있는 데이터가 있나요?
재현 방법은 다음과 같습니다: 사용자가 페이지를 새로고침하지 않고 여러 번 주제 하단의 “제안/관련” 링크를 통해 한 주제에서 다른 주제로 이동하면, 제 테스트에서는 JS 힙 크기가 원래 100MB에서 약 500MB까지 증가했습니다(특히 게시물이 많은 주제를 방문한 경우). 또한 홈 페이지로 돌아가도 해당 메모리가 해제되지 않습니다.
이 JS 힙 크기는 브라우저 콘솔의 성능 탭에서 확인할 수 있으며, 메모리 사용량은 브라우저의 프로세스 매니저에서 확인할 수 있습니다.
이 문제를 보여줄 영상(약 3분)을 PR에 첨부했습니다. 같은 페이지를 몇 시간 동안 사용하게 되면 상황이 더 악화됩니다.
여기에 브레이크포인트를 설정하면 _identityMap 항목 수가 증가하는 것을 확인할 수 있습니다.
다만 _identityMap이 이 문제의 근본 원인인지는 확실하지 않으며, 조사에 도움이 될 정보만 제공한 것입니다.
2개의 좋아요
saquetim
(Sérgio Saquetim)
1월 16, 2026, 7:58오후
8
main ← perf/prevent-evergrowing-cache-store
merged 09:14PM - 19 Jan 26 UTC
Fixes a memory leak reported by @small-lovely-cat in https://meta.discourse.org/… t/perf-there-seems-to-be-a-memory-leakage-in-frontend-store/393510/1
## Problem
The store's identity map holds strong references to every model instance ever fetched during a session. These references are never released, causing memory to grow unbounded as users navigate through the application.
Models for topics, posts, categories, and other resources accumulate indefinitely, even after the user has navigated away and the app no longer needs them.
## Why not FIFO/LRU?
Traditional cache eviction strategies don't work well for an identity map. If we evict an entry while the app still holds a reference to that model (e.g., it's rendered in a component), the object remains in memory anyway. Worse, the next fetch for that ID creates a *new* instance—consuming more memory and breaking identity semantics where the same ID should always return the same object.
## Solution
Introduce `WeakValueMap`, a Map that holds weak references to its values. When a model instance is no longer referenced anywhere else in the application, it becomes eligible for garbage collection, and the identity map entry is automatically cleaned up.
**Key implementation details:**
- `WeakRef` wraps cached values, allowing GC when unreferenced
- `FinalizationRegistry` removes stale map entries after values are collected
- Probabilistic sweep (~1% of `get()` calls) as a backup cleanup mechanism
This makes the identity map self-regulating—it naturally shrinks when models are no longer in use, while still preserving identity semantics for active models.
위의 PR은 OP에서 보고된 메모리 누수를 해결할 것입니다.
6개의 좋아요
sam
(Sam Saffron)
에 닫힘
1월 19, 2026, 9:00오후
9
이 주제는 20시간 후 자동으로 닫혔습니다. 더 이상 새 답글을 작성할 수 없습니다.