Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions docs/MOBILE_RUNBOOK.md
Original file line number Diff line number Diff line change
Expand Up @@ -439,6 +439,14 @@ PID=$(lsof -ti tcp:8081 -sTCP:LISTEN); lsof -p $PID | grep cwd # cwd가 지
kill $PID && (cd apps/mobile && npx expo start --dev-client --port 8081)
```

### 함정 12. 지도 조작 중 앱이 통째로 꺼진다 — 커스텀 뷰 마커 비트맵 recycle (라이브러리 버그)

**증상** — 붉은 에러 화면 없이 앱이 그냥 사라진다. `adb logcat -d -b crash`에 `SIGABRT` + `Abort message: 'JNI DETECTED ERROR ... bitmap decoding: could not lock pixels'` + `from com.naver.maps.map.renderer.MapRenderer.nativeRender()`가 찍히고, 직전에 `W/Bitmap: Called getDensity() on a recycle()'d bitmap!`가 있다.

**원인** — `@mj-studio/react-native-naver-map` 2.9.0 안드로이드의 `RNCNaverMapMarker.removeCustomView()`가 지도 아이콘이 아직 참조 중인 비트맵을 먼저 `recycle()`하고 아이콘을 교체한다. 커스텀 뷰 마커(경로 번호·클러스터·미션 이름표)가 언마운트되는 순간 GL 렌더 스레드가 그 비트맵을 잠그려다 네이티브 abort. 줌 변경으로 클러스터가 교체되거나 경로를 해제할 때 확률적으로 재현된다(2026-09-07 실측, 프로세스 uptime 182초). 에뮬레이터·Metro 문제가 아니다.

**대응** — `patches/@mj-studio__react-native-naver-map@2.9.0.patch`에 recycle 제거가 들어 있다(GC에 맡김). Kotlin 변경이라 **dev client 재빌드**가 필요하다 — 옛 APK를 쓰면 패치 전 코드로 돌아간다. 같은 시그니처가 다시 보이면 APK가 패치 이후에 빌드된 것인지부터 확인한다.

### 에뮬레이터 재현 성공 경로 (막혔을 때 통째로 다시 밟을 순서)

2026-08-20에 실제로 통한 경로다. 개별 대응이 안 먹으면 이 순서로 초기화한다.
Expand Down
2 changes: 2 additions & 0 deletions docs/STATUS.md
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,7 @@
- MSG-572: 업로드 미리보기 공개 범위 선택(웹 MSG-476 ① 이식) — `upload-flow-store`에 **영속 필드 `visibility: VideoVisibility`(초기 `"PUBLIC"`) + `setVisibility`**, `upload-flow-storage` 하위호환(필드 없음→PUBLIC, `VISIBILITY_OPTIONS` 밖 값→진행 없음 — `eventTarget` 패턴 미러), `confirm-input` 유니온 일반 분기만 `visibility` 필수 + `buildConfirmInput` 5번째 필수 인자, `upload-effects` 일반 body `visibility` 명시 전송(행사 body 무변경 — DTO 부재), `preview-screen` 위치 카드 아래 공개 범위 카드(ui-native `Selector type="radio"` + 행 `Pressable accessible role=radio` 44dp, 컨테이너 `radiogroup`, 행사 모드 미노출). 옵션 정본은 video-actions `VISIBILITY_OPTIONS` 재사용. 신규 파일 0·수정 9, `use-upload-mutations` 무수정(MSG-567 교집합 회피), 웹·packages 0줄
- MSG-578: 검색 실연동(웹 MSG-328·412 이식) — `features/search/model/zone-search.ts`(웹 복사 포팅 5함수 + 22케이스 + parity, `zoomForGridFocus` 미포팅), `api/` 옵션 팩토리+얇은 훅 3종(`use-place-search-query` 디바운스 300ms+`searchNow` · `use-trending-query` · `use-zones-query` Infinity 캐시 — 인증 게이트 없음), `ui/search-result-lists.tsx`(`TrendingList`·`GridResultList`·`PlaceResultList` 표시 전용), `search-screen.tsx` 재작성 — idle = **인기 검색어 → 전체 지역(`useExploreRegionsQuery` + `selectRegion` + `router.back()`, 홈이 그 지역 첫 격자 중심으로 `moveTo`)**, 입력 중 = 격자 섹션 → 장소 결과, placeholder "장소, 격자 검색". **최근 검색·최근 방문 섹션 제거**(사용자 결정, 웹 HomeSearchBox 미러) → `search-store`·`recent-history`·`entities/region/model/regions`·`match-region` 삭제. 홈 복귀는 `map-home/model/home-focus.ts`(`parseHomeFocus`·`homeFocusParams` — `/home?lat&lng&gridId&bounds&ts` 5키 항상 동봉, 우선순위 gridId > bounds > point) + GridMapRef `focusTo`(줌 <16이면 16 보장)·`fitBounds`(`animateCameraWithTwoCoords`) + 홈 `searchHighlight` state → `GridMap highlightCell`(마지막 1건 유지·교체). `shared/use-debounced-value.ts` 웹 시그니처(`{debounced, flush}`)로 교체. 모바일 테스트 1321 → **1349**
- `ui-native` 비파괴 확장 이력: `Avatar.fallbackIcon`(MSG-426, 미지정 시 렌더 불변) — `index.ts` diff 0줄 합의는 계속 유효. · `VideoCard.accessibilityLabel`(MSG-446, 미지정 시 렌더·낭독 불변) · `VideoRow`의 `accessibilityRole`을 `onPress` 조건부로 교정(MSG-446 — 목적지 없이도 버튼으로 낭독되던 결함, `VideoCard`와 같은 규칙)
- MSG-582: 네이버 지도 RN 라이브러리(`@mj-studio/react-native-naver-map` 2.9.0) **pnpm 패치 2건째** — `RNCNaverMapMarker.removeCustomView()`의 `customViewBitmap.recycle()` 제거(참조만 끊고 GC에 맡김). 커스텀 뷰 마커(경로 번호·클러스터·미션 이름표) 언마운트 시 GL 렌더 스레드가 recycle된 비트맵을 잠그려다 네이티브 abort로 앱이 통째로 꺼지던 라이브러리 버그. 패치 파일은 `patches/@mj-studio__react-native-naver-map@2.9.0.patch` 하나(MSG-445 onLoad `topLoaded` 패치와 같은 파일). Kotlin 변경이라 dev client 재빌드 필요 — 런북 함정 12

## 티켓 이력 (2026-08-13 이후 — 티켓당 한 줄 append)

Expand Down Expand Up @@ -235,3 +236,4 @@
- MSG-580: [모바일] 경로추천 칩 목록 상태에서 지도에 코스 경로선·번호 마커가 안 그려짐 — 사용자 QA("지도에 경로가 표시가 안 된다")로 하네스가 티켓 생성. 앱은 MSG-427 AC 10대로 선택 코스만 라인을 그렸고 웹은 목록 전체(`buildCourseRoutes`)로 갔던 파리티 갭. `courseRoutesOf` 신설 + GridMap `routes` prop(단일 `route`와 합류 렌더). 코스별 이름표는 미이식(Q4 유지). 경량 실행, 실기 확인
- MSG-581: [모바일] 광역 줌(bbox > 0.5°)에서 테마 칩 미션 목록 0개 — 경로선 미표시·클러스터 16/시트 0 불일치(세 칩 공통) — 사용자 QA 3건으로 하네스가 티켓 생성. 원인은 미션 조회의 0.5° 초과 `enabled=false` + MSG-579가 비활성 placeholder를 비운 결과(예고된 후속). `viewportQueryArgs` 대신 `clampBoundsToSpan`으로 요청 bbox 클램프. 경량 실행, 두 번째 AVD + Metro 8083 실기 4장
- MSG-578: [모바일] 검색 실연동 — 인기 검색어·장소 검색·격자 검색(웹 MSG-328·412 이식). MSG-297 목 화면(구 목록 로컬 매칭)을 실 API 3종 + zones 로컬 역파싱으로 교체하고 결과 탭을 기존 `/home` params 복귀 경로 확장(격자 줌 보장+점선 하이라이트, 구역 fitBounds)으로 배선. 검증 중 사용자 결정으로 **최근 검색 섹션 제거**(웹 따라가기, 스토어 삭제). 검증 S10이 `navigate("/home")` 리마운트 버그(선택 지역 소실)를 잡아 `router.back()`으로 수정. 전체 지역 탭은 DTO에 좌표가 없어 시트용 격자 목록의 첫 격자 중심으로 지도 이동(A1 승인 → 사용자 번복 "지도도 옮겨야")
- MSG-582: [모바일] 지도 조작 중 앱 강제 종료 — 사용자 QA("갑자기 앱이 꺼지는데")로 하네스가 티켓 생성. `adb logcat -b crash`의 `could not lock pixels` + `recycle()'d bitmap` 시그니처로 `@mj-studio/react-native-naver-map` 안드로이드 `removeCustomView()`의 recycle 선행 버그 특정. 앱 코드 0줄, pnpm 패치 1줄 + 런북 함정 12. 경량 실행, 패치 APK 재빌드 후 실기 콜드 스타트 확인
1 change: 1 addition & 0 deletions docs/decisions/DECISIONS.md
Original file line number Diff line number Diff line change
Expand Up @@ -657,3 +657,4 @@
| 2026-09-07 | MSG-578 | 결정(codex 리뷰 P2 ①): 검색 결과 → 홈 복귀를 `router.navigate`에서 **`router.dismissTo`(POP_TO)** 로 — 기존 홈 인스턴스로 돌아가 params만 갱신 | 실기: 줌 18에서 격자 검색 후 복귀 시 줌이 16으로 리셋(홈 리마운트 → GridMap `initialZoom`). SDK `animateCameraTo`는 zoom 생략 시 `scrollTo`라 `focusTo`는 무죄. `dismissTo` 뒤 임시 마운트 로그로 리마운트 0회·줌 18 유지·하이라이트 정상 확인. 빌더의 "홈 마운트 유지" 전제가 틀렸고 params 병합 관찰만 맞았다 |
| 2026-09-07 | MSG-578 | 결정(codex 리뷰 P2 ②): 홈이 `selectedRegion`(싱글턴)이 채워지면 테마·미션·격자·이벤트 선택을 비우는 effect 추가 — 검색의 전체 지역 탭이 칩 활성 중에도 지역 시트에 닿게 | `homePanelKind`는 격자 > 상세 > 칩 목록 > 기본 순이라 칩이 켜져 있으면 고른 지역이 헤더에 못 온다. 선택 3종은 홈 로컬 state라 검색 화면에서 못 지운다 → 홈 effect가 유일한 자리. `panel-branch` 우선순위 변경은 parity 파일이라 기각. 실기: 지역축제 칩 → 검색 → 서초2동 탭 → 칩 해제 + 헤더 서초2동 |
| 2026-09-07 | MSG-578 | 결정(사용자, PR 리뷰 중 — A1 번복): 지역을 고르면(검색 전체 지역 탭·홈 "전체 보기") 홈이 **그 지역 격자 목록의 첫 격자(최신순) 중심으로 `moveTo`** 한다 — `selectedRegion` + `regionGrids.data`(regionCode 에코 일치) effect, 지역당 1회(`movedToRegionRef`) | 사용자: "아 지도도 옮겨야하는데". 지역 API에 좌표가 없어 스펙 A1은 "시트만 교체"였으나, 시트가 이미 받는 `GET /api/regions/{code}/grids` 카드에 `gridX·gridY`(5179)가 있어 요청 추가 없이 중심을 구할 수 있다. 이동이 `onViewportChange → clearSelectedRegion`을 부르지만 새 중심의 라이브 행정동이 곧 그 지역이라 헤더가 이어진다(실기: 서초2동 → 강남 I-6). 웹 `RegionListView`는 안 움직이는데 모바일만 움직이는 parity 차이는 사용자 결정으로 수용 |
| 2026-09-07 | MSG-582 | 결정: 라이브러리 버그를 **업그레이드가 아니라 기존 pnpm 패치 파일에 1줄 추가**로 해소 — `removeCustomView()`의 `recycle()` 제거(`customViewBitmap = null`) | 크래시 시그니처가 recycle 선행 → GL 스레드 lock 실패로 명확. Android O 이후 비트맵은 네이티브 힙을 GC가 회수하므로 명시 recycle 없이 안전. 대안 (a) 아이콘 교체 후 recycle로 순서만 바꾸기 — GL 스레드가 다음 프레임까지 옛 아이콘을 잡고 있을 수 있어 레이스가 남는다, 기각. (b) 라이브러리 업그레이드 — 기존 onLoad 패치 재작업 + 네이티브 의존성 재검증 비용, 상위 버전이 이 경로를 고쳤는지 미확인, 기각. 업스트림 제보는 후속 |
60 changes: 60 additions & 0 deletions docs/spec/MSG-582.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
# MSG-582: [모바일] 지도 조작 중 앱 강제 종료 — 네이버 지도 RN 라이브러리 커스텀 뷰 마커 비트맵 recycle 크래시 패치

> 원문: https://soma17-msg.atlassian.net/browse/MSG-582 (하네스 생성, 2026-09-07 — 사용자 QA "갑자기 앱이 꺼지는데")
> **수정 범위: `patches/@mj-studio__react-native-naver-map@2.9.0.patch` 1줄 + `pnpm-lock.yaml` 패치 해시 + `docs/MOBILE_RUNBOOK.md` 함정 12.** 앱 코드(`apps/mobile/src`)·`apps/web`·`packages/**` 0줄.

## 기획 요약
지도 홈에서 조작 중 붉은 에러 화면 없이 앱이 통째로 사라진다. 에뮬레이터 재가동 직후 약 3분 뒤 재현.

## 0. 착수 실측 (develop `43f425e`, 에뮬레이터 FillMap_Pixel8)

| 사실 | 실측 | 함의 |
|---|---|---|
| 크래시 종류 | `adb logcat -b crash`: `signal 6 (SIGABRT)`, `Abort message: 'JNI DETECTED ERROR IN APPLICATION: ... bitmap decoding: could not lock pixels'`, `from com.naver.maps.map.renderer.MapRenderer.nativeRender()`, 스레드 `GLThread 139` | JS 에러가 아닌 네이티브 abort — RN 에러 화면이 뜰 수 없다 |
| 직전 경고 | `W/Bitmap: Called getDensity() on a recycle()'d bitmap!` (크래시 6ms 전) | 지도 SDK가 이미 recycle된 비트맵을 아이콘으로 그리려 했다 |
| 라이브러리 코드 | `RNCNaverMapMarker.kt:91 removeCustomView()`: `customViewBitmap.recycle()` → `setImageWithLastImage()` 순서 | 아이콘이 아직 그 비트맵을 참조하는 상태에서 recycle |
| 앱의 커스텀 뷰 마커 | `grid-map.tsx` 경로 번호 마커·클러스터 마커·미션 이름표 (`NaverMapMarkerOverlay` 자식 뷰) | 줌 변경·코스 진입/이탈·칩 해제마다 언마운트 = 트리거 |
| 기존 패치 | `pnpm-workspace.yaml` `patchedDependencies` → 같은 패치 파일에 onLoad(`topLoaded`) 패치 존재 | 새 패치를 같은 파일에 병합 |
| 메모리·GPU | AVD RAM 2G/가용 1.2G, GPU auto | 자원 부족 아님 |

## 1. 결정

| # | 결정 | 근거 |
|---|---|---|
| D1 | `removeCustomView()`에서 `recycle()` 호출을 제거하고 `customViewBitmap = null`로 참조만 끊는다 | Android O 이후 비트맵 픽셀은 네이티브 힙을 GC가 회수 — 명시 recycle 불필요. 1줄 diff |
| D2 | 순서 교체(아이콘 교체 후 recycle)는 기각 | GL 스레드가 다음 프레임까지 옛 아이콘을 잡을 수 있어 레이스가 남는다 |
| D3 | 라이브러리 업그레이드 기각, 2.9.0 유지 | 기존 onLoad 패치 재작업 + 네이티브 의존성 재검증 비용. 업스트림 제보는 후속 |
| D4 | `pnpm patch --edit-dir` → 수정 → `pnpm patch-commit`으로 기존 패치 파일에 병합 | 패치 파일 1개 유지, lock 해시 자동 갱신 |

## 2. 수용 기준

| # | 기준 | 유형 | 검증 |
|---|---|---|---|
| L1 | 패치 파일에 `recycle()` 제거 diff가 있고, 설치된 라이브러리 소스에 반영된다 | 로직 | `grep "customViewBitmap = null" patches/…` + `node_modules` 심링크 대상 소스 |
| G1 | dev client 재빌드 시 `:mj-studio_react-native-naver-map:compileDebugKotlin` 재실행, BUILD SUCCESSFUL | 게이트 | 빌드 로그 |
| S1 | 패치 APK 콜드 스타트 후 앱이 Metro에 붙어 정상 기동 | 화면 | 실기 |
| S2 | 줌 인/아웃 반복(클러스터 교체)·코스 진입/이탈에도 앱이 종료되지 않고 `adb logcat -b crash` 무출력 | 화면 | 실기 |

## 3. 리스크

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟢 사소한 제안 — "3. 리스크"에 메모리 트레이드오프 한 줄 추가 검토

patch 파일 인라인 코멘트에도 적었듯, recycle 제거는 크래시 레이스는 없애지만 대신 비트맵 회수를 GC 타이밍에 맡기는 트레이드오프가 생깁니다. 줌 반복처럼 커스텀 뷰 마커가 빈번히 교체되는 조작에서 메모리 사용량이 늘어날 가능성이 있는데, 이 리스크 절에는 확률적 재현 이슈만 있고 언급이 없습니다. D1 결정 근거("GC가 회수하므로 안전")와 짝을 이루는 리스크로 한 줄 추가해두면 함정 12를 보는 다음 사람이 "이 시그니처는 없는데 대신 느려짐/OOM이 보인다"는 경우도 바로 이 티켓과 연결 지을 수 있습니다.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

실측으로 확인했습니다 (에뮬레이터, 핀치 줌 인/아웃 10회 반복, dumpsys meminfo): Java 힙 22.0→27.9MB, 3분 뒤 22.5MB로 복귀. 네이티브 힙 407→416→412MB(지도 타일 캐시 변동 범위). 크래시 0. 마커 비트맵은 ARGB_4444 수십 px라 개당 수 KB이고 GC가 회수하는 것이 확인돼 지연 recycle 경로는 도입하지 않았습니다. 스펙 "3. 리스크"에 트레이드오프 + 실측치를 추가했습니다.

- recycle 제거로 비트맵 회수가 GC 타이밍에 맡겨진다(클로드 리뷰 🟡). 실측(에뮬레이터, 핀치 줌 인/아웃 10회 반복, `dumpsys meminfo`): Java 힙 22.0→27.9MB, 3분 뒤 22.5MB로 복귀 · 네이티브 힙 407→416→412MB(지도 타일 캐시 변동 범위). 마커 비트맵은 `ARGB_4444` 수십 px라 개당 수 KB이고 GC가 회수함을 확인 — 누적 OOM 리스크는 낮다. 크래시 없이 느려짐·OOM이 보이면 이 티켓과 연결
- 확률적 재현이라 S2는 "재현 안 됨"이 곧 증명은 아니다. 시그니처가 다시 보이면 APK가 패치 이후 빌드인지부터 확인(런북 함정 12).

---

## 작업 로그 (2026-09-07)

**변경 파일**
- `patches/@mj-studio__react-native-naver-map@2.9.0.patch` — `RNCNaverMapMarker.kt` hunk 추가 (+15)
- `pnpm-lock.yaml` — 패치 해시 갱신
- `docs/MOBILE_RUNBOOK.md` — 함정 12 신설
- `docs/STATUS.md` · `docs/decisions/DECISIONS.md` · 본 파일

**실측**
- L1 ✅ 패치 파일 grep 1건, `apps/mobile/node_modules/@mj-studio/react-native-naver-map` 심링크가 새 해시(`b41f33e…`) 디렉토리로 교체, 그 소스에 `customViewBitmap = null` 반영
- G1 ✅ `expo run:android --no-bundler --device FillMap_Pixel8` — `compileDebugKotlin` 재실행, BUILD SUCCESSFUL in 26s
- S1 ✅ force-stop 후 `localhost:8081` 딥링크 콜드 스타트, `Running "main"` 로그, 로그인 화면 표시
- S2 ⏳ 사용자 실기 진행 중(세션의 원래 목적이 안드로이드 테스트) — 재현 조작 반복은 사용자 몫. 스크린샷 없음(크래시 부재는 화면으로 증명되지 않음)

**검토한 대안** — 결정 D2·D3 참조.

**후속** — 업스트림(mj-studio/react-native-naver-map) 이슈 제보.
15 changes: 15 additions & 0 deletions patches/@mj-studio__react-native-naver-map@2.9.0.patch
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,21 @@ index c92093f93ff92013db5574361eb0a21853f356cd..7dacb623e928c3bfedc973775f7b70ae
registerDirectEvent(this, NaverMapOptionChangeEvent.EVENT_NAME)
registerDirectEvent(this, NaverMapCameraChangeEvent.EVENT_NAME)
registerDirectEvent(this, NaverMapCameraIdleEvent.EVENT_NAME)
diff --git a/android/src/main/java/com/mjstudio/reactnativenavermap/overlay/marker/RNCNaverMapMarker.kt b/android/src/main/java/com/mjstudio/reactnativenavermap/overlay/marker/RNCNaverMapMarker.kt
index 509e1ec715d475671f26797a70fc2872cd6fde9c..1d771624fe55010629419f231079f91ba0f6c6a8 100644
--- a/android/src/main/java/com/mjstudio/reactnativenavermap/overlay/marker/RNCNaverMapMarker.kt
+++ b/android/src/main/java/com/mjstudio/reactnativenavermap/overlay/marker/RNCNaverMapMarker.kt
@@ -88,7 +88,9 @@ class RNCNaverMapMarker(
fun removeCustomView(index: Int) {
customView = null
ViewChangesTracker.getInstance().removeMarker(this)
- if (customViewBitmap != null && !customViewBitmap!!.isRecycled) customViewBitmap!!.recycle()
+ // FillMap 패치: overlay.icon이 아직 이 비트맵을 참조하는 상태에서 recycle하면 GL 렌더 스레드가
+ // "could not lock pixels"로 네이티브 abort(앱 종료)한다. GC에 맡긴다 — 2026-09-07 실측.
+ customViewBitmap = null

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 권장 — recycle 제거로 인한 비트맵 GC 지연(메모리) 트레이드오프가 문서화 안 됨

recycle()을 없애고 GC에 맡기는 방향 자체는 크래시(레이스) 해소로는 타당합니다. 다만 이 마커들은 스펙에도 적혀 있듯 "줌 변경으로 클러스터가 교체"될 때마다 대량으로 마운트/언마운트되는 경로입니다 (grid-map.tsx의 클러스터·경로 번호 마커). recycle 없이 GC에만 의존하면:

  • 커스텀 뷰 마커 비트맵은 보통 View.draw()로 렌더한 소프트웨어 비트맵이라 Java 힙에 남습니다. 줌을 빠르게 반복하면 이전 프레임들의 비트맵이 GC 사이클 전까지 누적돼 메모리 압박(→ 다른 원인의 OOM/버벅임)을 유발할 수 있습니다.
  • docs/spec/MSG-582.md의 "3. 리스크" 절이 확률적 재현 이슈만 다루고 이 메모리 트레이드오프는 언급하지 않습니다.

D2(순서만 바꾸는 대안)가 기각된 근거는 납득되지만, 대안으로 "언마운트 시 GL 스레드가 이번 프레임 렌더를 마쳤다고 보장된 뒤(예: 다음 카메라 idle·프레임 콜백)에 recycle" 같은 지연 recycle 경로도 검토해볼 만합니다. 최소한 지속적인 줌 반복 상황에서 메모리 사용량(adb shell dumpsys meminfo)을 실기로 한 번 확인해두면 좋겠습니다 — 사용자 QA가 "지도 조작 중"이라 정확히 이 패턴입니다.

(추측 포함: customViewBitmap이 커스텀 뷰 스냅샷용 소프트웨어 비트맵이라는 전제 하의 지적이며, 하드웨어 비트맵이라면 해당 없음)

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

실측으로 확인했습니다 (에뮬레이터, 핀치 줌 인/아웃 10회 반복, dumpsys meminfo): Java 힙 22.0→27.9MB, 3분 뒤 22.5MB로 복귀. 네이티브 힙 407→416→412MB(지도 타일 캐시 변동 범위). 크래시 0. 마커 비트맵은 ARGB_4444 수십 px라 개당 수 KB이고 GC가 회수하는 것이 확인돼 지연 recycle 경로는 도입하지 않았습니다. 스펙 "3. 리스크"에 트레이드오프 + 실측치를 추가했습니다.

isImageSetFromSubview = false
setImageWithLastImage()
super.removeView(children.elementAt(index))
diff --git a/lib/typescript/commonjs/src/component/NaverMapView.d.ts b/lib/typescript/commonjs/src/component/NaverMapView.d.ts
index 83f41067be85014cf8c43f5d970c9b361e12cf12..f6e7e8041b27b25ea1100095dbe16e342b4a105d 100644
--- a/lib/typescript/commonjs/src/component/NaverMapView.d.ts
Expand Down
6 changes: 3 additions & 3 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading