관리 메뉴

김종권의 iOS 앱 개발 알아가기

[iOS - swift] 3.memgraph 메모리 프로파일링 - 메모리 주소로 코드 역추적하기 (malloc_history , Malloc Stack Logging) 본문

iOS 응용 (swift)

[iOS - swift] 3.memgraph 메모리 프로파일링 - 메모리 주소로 코드 역추적하기 (malloc_history , Malloc Stack Logging)

jake-kim 2023. 12. 26. 00:25

* 가장 기초) iOS 메모리 기초 개념 - virtual memory, dirty memory, clean memory, compressed memory, swapped memory 이해하기 포스팅 글

 

1. memgraph 메모리 프로파일링 - 샘플 준비

2. memgraph 메모리 프로파일링 - vmmap을 사용하여  문제가 있는 코드의 메모리 주소 찾아내기

3. memgraph 메모리 프로파일링 - 메모리 주소로 코드 역추적하기 (malloc_history , Malloc Stack Logging)

malloc_history로 코드 역추적하기

  • malloc_history를 사용하면 참조 타입 인스턴스들이 할당된 코드를 역추적이 가능
  • 단, memgraph를 얻어올때 Xcode에서 "Malloc Stack Logging"옵션 활성화가 필요
    • Malloc Stack Logging활성화: Edit Schemes >  Run > Diagonositics

  • 만약 이 옵션이 켜져있지 않은 상태에서 memgraph를 얻어왔다면 이 옵션을 활성화하고 다시 memgraph 파일 획득이 필요
  • 다시 얻어낸 memgraph 파일을 사용하여 malloc_history 명령어를 수행
    • 복사한 메모리 주소를 그대로 붙여넣기 하면 안되고, 0x을 앞에 붙이기
    • 메모리 주소를 알아내는 방법은 이전 포스팅 글 참고

명령어)

malloc_history {name}.memgraph -fullStacks {address}
  • 수행
malloc_history sample.memgraph -fullStacks 0x2abd40000

 

결과) 

  • 내 애플리케이션에서 어떤 부분의 코드가 추적이 되었는지 확인이 가능
    • ViewController.viewDidLoad()에서, addImages()가 호출되었고... _UIGraphicsGetImageFromCurrentImageContext를 사용하고 있다는 것도 확인

  • 아래 코드라는것을 확인 가능
func addImages() {
    let image = UIImage(named: "high_resolution_img")
    
    (0...10000)
        .forEach {
            print($0)
            let imageView = UIImageView(image: resizeImage(image: image!, targetSize: .init(width: 300, height: 300)))
            stackView.addArrangedSubview(imageView)
        }
}

func resizeImage(image: UIImage, targetSize: CGSize) -> UIImage {
    let size = image.size

    let widthRatio  = targetSize.width  / size.width
    let heightRatio = targetSize.height / size.height

    var newSize: CGSize
    if widthRatio > heightRatio {
        newSize = CGSize(width: size.width * heightRatio, height: size.height * heightRatio)
    } else {
        newSize = CGSize(width: size.width * widthRatio,  height: size.height * widthRatio)
    }

    UIGraphicsBeginImageContextWithOptions(newSize, false, 1.0)
    image.draw(in: CGRect(origin: .zero, size: newSize))

    let newImage = UIGraphicsGetImageFromCurrentImageContext()
    UIGraphicsEndImageContext()

    return newImage ?? image
}

 

* 참고

- https://developer.apple.com/videos/play/wwdc2018/416/

Comments