Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Refactor] #529 - 앱 메모리 최적화(솝탬프, 콕찌르기, 마이페이지, 홈캘린더) #532

Merged
merged 9 commits into from
Apr 3, 2025

Conversation

yungu0010
Copy link
Contributor

@yungu0010 yungu0010 commented Apr 1, 2025

🌴 PR 요약

앱 전체적으로 발생하고 있는 메모리 누수 최적화를 진행했습니다.

🌱 작업한 브랜치

🌱 PR Point

문제 발생

#528 이슈를 해결하던 도중, 솝탬프 진입 횟수만큼 MissionListRepository가 메모리에 남아있는 현상을 발견했습니다.
메모리 그래프를 살펴보니, MissionListVCdeinit 되지 않아 ViewModel -> UseCase -> Repository까지 모두 메모리에 남아 누수가 발생하고 있었습니다.

앱의 다른 부분도 확인해보았는데 4개의 화면에서 동일한 누수가 발생하고 있었습니다. 첨부한 이미지는 마이페이지, 홈캘린더, 콕찌르기, 솝탬프를 각각 5회 진입 한 후 메모리 사용량입니다.
memory누수

SOPT-iOS-Demo Repository TabBarFeatureInterface
스크린샷 2025-04-02 오후 3 53 45 스크린샷 2025-04-02 오후 3 58 04

각 플로우의 진입 횟수만큼 객체가 쌓이는 것을 확인할 수 있었습니다.

문제 해결

1️⃣ HomeCalendarDetail

  • self를 직접 캡처하고 있던 클로저 1곳을 [weak self]로 수정했습니다.

2️⃣ MyPage
image

  • 메모리 그래프에서 총 8개의 클로저가 VC를 캡처하고 있는 것을 확인했습니다.
  • 해당 클로저들에서 self[weak self]로 수정하여 순환 참조를 끊었습니다.

3️⃣ MissionList
image

  • menuItems 구성 시 self를 직접 캡처하고 있어 [weak self]로 변경했습니다.
  • 하지만 여전히 메모리 그래프에서 1개의 클로저가 VC를 참조하고 있었습니다.

MissionListVC

  • 메모리 그래프를 확인해보니, UICollectionViewCompositionalLayout에서 누수 원인을 찾을 수 있었고, 관련 코드를 찾아 수정했습니다.

4️⃣ PokeMainVC
Poke

  • 아래와 같이 VC가 클로저 내에서 직접 사용되고 있어 순환 참조가 발생하고 있었습니다.
 pokeMain.vm.onNewFriendMade = { [weak self] friendName in
            ...
            // Coordinator의 rootController를 사용하지 않고 vc를 생성하고 있음
            let pokeMakingFriendCompletedVC = self.factory.makePokeMakingFriendCompleted(friendName: friendName).viewController
            pokeMain.vc.viewController.present(pokeMakingFriendCompletedVC, animated: false)
            ...
        }
  • 해당 부분도 [weak self]로 캡처하도록 수정한 뒤, deinit이 정상적으로 동작하는 것을 확인했습니다.

결과

스크린샷 2025-04-02 오후 4 33 45 스크린샷 2025-04-02 오후 4 35 13
  • 코드 수정 후 메모리 그래프와 deinit 로그로 VC 메모리가 더 이상 남아있지 않는 것을 확인할 수 있었습니다!
  • 코드 수정 부분의 기능이 정상적으로 동작하는 것도 확인했습니다.
  • 하지만 여전히 Poke에서 사용되는 일부 View가 메모리에 남아있어, [Refactor] 콕 찌르기 메모리 최적화 #533 이슈에서 이어서 수정해보도록 하겠습니다!

📌 참고 사항

  • MissionListVCspace 간격을 4로 수정했습니다.
  • OPNavigationBar에서도 VC를 주입받고 있어서 VC를 제거하려고 했으나, 너무 많은 플로우에서 해당 navigationBar를 사용하고 있고 메모리 누수와 직접적인 연관이 없어 수정하지 않았습니다. ([Refactor] 화면 전환 방식 리팩토링 (Coordinator, Router) #515 에서 함께 진행해보아요)
  • 일부 레거시 코드에서 VC에서 클로저 호출 -> Coordinator에서 클로저 구현 방식으로 화면전환을 하고 있는 부분이 있는데,
    View는 UI만, ViewModel은 상태 관리, Coordinator가 화면전환의 역할을 갖고 있는만큼 VC -> VM -> Coordinator흐름으로 리팩토링 하는 걸 제안드립니다 !

📮 관련 이슈

@yungu0010 yungu0010 requested a review from dlwogus0128 April 1, 2025 18:46
Copy link

height bot commented Apr 1, 2025

Link Height tasks by mentioning a task ID in the pull request title or commit messages, or description and comments with the keyword link (e.g. "Link T-123").

💡Tip: You can also use "Close T-X" to automatically close a task when the pull request is merged.

@yungu0010 yungu0010 requested a review from meltsplit April 1, 2025 18:46
@yungu0010 yungu0010 added Refactor 전면 수정 윤서🍉 labels Apr 1, 2025
@yungu0010 yungu0010 self-assigned this Apr 2, 2025
Copy link
Contributor

@dlwogus0128 dlwogus0128 left a comment

Choose a reason for hiding this comment

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

좋아요~!!! 네비바랑 화면전환의 책임분리가 제대로 되어있지 않은 부분들 리팩하면서 한꺼번에 고쳐보아용 🚀

@@ -227,27 +227,27 @@ extension AppMyPageVC {

// TODO: - (@승호): 적절히 객체에 위임하기
private func addTabGestureOnListItems() {
self.servicePolicySectionGroup.addTapGestureRecognizer {
self.onPolicyItemTap?()
self.servicePolicySectionGroup.addTapGestureRecognizer { [weak self] in
Copy link
Contributor

Choose a reason for hiding this comment

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

어쩐지 마이페이지만 진입하면 앱 메모리가 증가한다 했었는데~!

@@ -57,21 +57,21 @@ final class PokeCoordinator: DefaultCoordinator {

pokeMain.vm.onPokeButtonTapped = { [weak self] userModel in
guard let self else { return .empty() }
return self.showMessageBottomSheet(userModel: userModel, on: pokeMain.vc.viewController)
return self.showMessageBottomSheet(userModel: userModel, on: self.rootController)
Copy link
Contributor

Choose a reason for hiding this comment

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

같은 뷰를 갖고 있었던 솝마디도 똑같은 부분에서 누수가 있었어유. 굿굿

@yungu0010 yungu0010 merged commit 4081e2d into develop Apr 3, 2025
@yungu0010 yungu0010 deleted the refactor/#529-app-memory-leak branch April 3, 2025 09:07
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[Refactor] 앱 메모리 최적화(솝탬프, 콕찌르기, 마이페이지, 홈캘린더)
2 participants