Instruments — iOS, macOS, tvOS 및 watchOS 앱의 성능 분석을 위해 Xcode에 내장된 프로파일러입니다. 이 도구는 CPU, 메모리, 네트워크, 그래픽 및 에너지 소비를 실시간으로 측정하기 위한 템플릿 세트를 제공합니다. Apple Developer Documentation에 따르면 Instruments는 개발의 모든 단계(누수 검색부터 앱 시작 시간 최적화까지)에서 사용됩니다.
핵심 내용
Instruments — Xcode의 일부이며 Sun Microsystems가 개발한 DTrace 기술을 기반으로 하는 프로파일링 및 추적 시스템입니다. Instruments는 수십 개의 프로파일링 도구(템플릿)를 단일 인터페이스에 통합합니다: 템플릿을 선택하고 Xcode를 통해 앱을 실행한 후 데이터 수집을 시작하면 됩니다.
Instruments의 아키텍처는 클라이언트-서버 모델을 기반으로 합니다: 장치의 에이전트가 데이터를 수집하고 USB 연결을 통해 Mac으로 전송합니다. 이는 프로파일러가 앱 성능에 미치는 영향을 최소화합니다 — Instruments는 주로 호스트 측에서 작동합니다. WWDC 2022에 따르면 1ms 샘플링 속도에서 Time Profiler의 오버헤드는 3% 미만입니다.
Instruments는 사용자 정의 템플릿을 지원합니다 — 개발자는 단일 프로파일링 세션에서 여러 도구를 결합할 수 있습니다. 예를 들어, Time Profiler + Allocations + Leaks를 동시에 실행하고 CPU 피크와 메모리 할당 간의 상관관계를 확인할 수 있습니다. 이는 각 구성 요소를 개별적으로 분석할 때는 얻을 수 없는 성능의 전체적인 그림을 제공합니다.
Xcode에는 16개의 사전 설치된 Instruments 템플릿이 포함되어 있습니다: Time Profiler, Allocations, Leaks, Energy Log, Network, Core Animation, Metal System Trace, File Activity, System Trace 등. 각 템플릿은 특정 작업에 최적화되어 있으며 올바른 트리거 및 필터 설정으로 사전 구성되어 있습니다.
Time Profiler — 가장 많이 사용되는 Instruments 템플릿입니다. 콜 스택 샘플링을 기반으로 작동합니다: 1~10밀리초마다 시스템이 앱의 모든 스레드 콜 스택을 기록합니다. 세션 중지 후 Instruments는 샘플을 합산하여 어떤 메서드와 함수가 가장 많은 시간을 소비했는지 보여줍니다. 결과는 Call Tree(자체 가중치 순으로 정렬된 콜 트리)로 표시됩니다.
Time Profiler의 핵심 메트릭은 Self Weight(자식 메서드 호출을 제외한 메서드 내에서 직접 소비된 시간)입니다. 실제로 프로세서에 부하를 주는 함수를 보여주는 것은 Self Weight입니다. Weight(자식 메서드를 포함한 총 시간)는 오해의 소지가 있습니다: Weight가 높은 메서드는 단순히 다른 느린 메서드를 호출하고 있을 수 있으며, 자체는 빠를 수 있습니다.
import UIKit
class ImageGalleryViewController: UIViewController {
// Time Profiler는 cellForItemAt의 Self Weight = 40%를 보여줍니다
// 그 내부에서 decodeImage가 35%를 차지 — 이것이 병목입니다
func collectionView(
_ collectionView: UICollectionView,
cellForItemAt indexPath: IndexPath
) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(
withReuseIdentifier: "ImageCell",
for: indexPath
) as! ImageCell
// ❌ decodeImage — 병목(Self Weight = 35%)
cell.imageView.image = UIImage(contentsOfFile: imagePath)
return cell
}
}
Time Profiler 분석 시 com.apple.main-thread에서 실행되는 메서드에 주목하세요. 메인 스레드의 Self Weight가 프레임당 16ms 임계값을 초과하면 UI가 느려집니다. 이러한 문제의 해결책은 이미지 디코딩, 레이아웃 계산 및 데이터 처리를 Grand Central Dispatch(GCD)를 사용하여 메인 스레드에서 백그라운드 스레드로 이동하는 것입니다.
Call Tree — Self Weight 순으로 정렬된 모든 메서드 호출의 계층적 표현입니다. Call Tree에서 가장 무거운 메서드가 첫 번째 줄입니다. 줄을 확장하면 해당 메서드가 호출한 자식 메서드와 그들이 소비한 시간을 볼 수 있습니다. Self Weight(자체 시간)가 Weight(총 시간)를 크게 초과하는 메서드를 찾으세요 — 이는 동기 차단 및 대기의 징후입니다.
Allocations — 앱의 모든 메모리 할당을 모니터링하는 도구입니다. 어떤 객체가, 몇 개나, 어떤 총 크기로 각 순간에 생성되는지 보여줍니다. Android Studio의 Memory Profiler와 달리 Allocations는 Heapshot(두 스냅샷을 비교할 수 있는 라이브 객체의 순간 스냅샷)을 지원합니다.
Allocations의 인터페이스는 두 가지 주요 섹션으로 구성됩니다: All Allocations(객체 유형별 총 통계) 및 Call Trees(객체를 생성하는 메서드별 콜 트리). 누수를 찾으려면 Heapshot Analysis를 사용하세요: 시나리오 실행 전에 스냅샷을 찍고, 시나리오를 실행하고, 후에 스냅샷을 찍어 어떤 새 객체가 메모리에 남아 있는지 비교합니다.
Apple Developer Documentation에 따르면 Allocations에서 발견되는 가장 일반적인 누수 패턴은 컬렉션 스크롤 시 UIView 및 CALayer의 과도한 생성입니다. 스크롤할 때마다 라이브 UIView 수가 증가하는데 컬렉션이 셀을 재사용한다면 — 어딘가에서 추가 뷰가 이전 뷰를 해제하지 않고 생성되고 있습니다. Allocations는 이러한 뷰가 생성되는 정확한 콜 스택을 보여줍니다.
| 파라미터 | 설명 | 확인할 사항 |
|---|---|---|
| # Living | 이 유형의 라이브 객체 수 | 시나리오 반복 시 안정적이어야 함 |
| # Transient | 기간 내 생성 및 해제된 객체 | 급격한 스파이크 — 과도한 할당의 징후 |
| Total Bytes | 이 유형의 총 메모리 볼륨 | 장치의 총 사용 가능 RAM과 비교 |
Heapshot — Allocations에서 라이브 객체의 순간 스냅샷입니다. 시나리오 실행 전에 Heapshot을 찍고, 시나리오를 실행하고, 두 번째 Heapshot을 찍습니다. 스냅샷 간의 차이는 생성되었지만 해제되지 않은 객체를 보여줍니다. 이상적인 결과는 임시 객체(Autorelease pool)만 증가하는 것입니다. 정확한 분석을 위해 단일 세션에서 Allocations + Leaks 조합을 사용하세요. Allocations는 어떤 객체가 해제되지 않는지, Leaks는 그 이유(어떤 강한 참조가 유지하고 있는지)를 보여줍니다. 누수가 의심될 때마다 이중 세션을 실행하세요.
Leaks — iOS 및 macOS 앱의 메모리 누수 탐지를 위한 특화된 도구입니다. 단순히 할당을 보여주는 Allocations와 달리 Leaks는 retain cycles(두 개 이상의 객체가 서로를 강한 참조로 유지하는 상황)을 찾기 위해 힙을 적극적으로 스캔합니다.
Leaks는 Cycles & Roots(객체 유지 그래프 시각화 도구)와 함께 작동합니다. 누수가 감지되면 Leaks는 사이클의 모든 객체, retain count 및 참조가 전달되는 정확한 필드를 보여줍니다. 개발자는 그래프를 보고 어떤 참조를 weak로 바꿔야 하는지 이해하기만 하면 됩니다.
이 도구는 타임라인에서 누수를 빨간색 마커로 자동 강조 표시합니다. Leaks는 실시간으로 작동합니다: 시스템이 누수를 감지하는 즉시 개발자에게 알립니다. 이를 통해 덤프 및 사후 분석을 기다리지 않고 “현장에서” 문제를 해결할 수 있습니다.
WWDC 2022에 따르면 Leaks는 복잡한 다단계 retain cycles(예: 3개 이상의 객체가 강한 참조의 폐쇄 체인을 형성하는 경우)도 감지할 수 있습니다. 이러한 사이클 진단에는 Cycles & Roots 그래프가 필수적입니다: 객체가 서로를 어떻게 참조하는지 시각적으로 보여줍니다.
그래프의 각 노드는 객체, 각 화살표는 강한 참조입니다. 사이클은 화살표의 폐쇄 루프입니다. 노드의 색상은 상태를 나타냅니다: 빨간색 — 누수된 객체, 초록색 — 루트(GC Root), 회색 — 중간 객체. 누수를 수정하려면 로직을 깨뜨리지 않고 weak로 만들 수 있는 화살표를 찾아 코드에서 참조 유형을 변경하세요.
Energy Log — 앱의 에너지 소비를 측정하는 Instruments 템플릿입니다. 장치의 하드웨어 센서(CPU 부하, Wi-Fi 및 셀룰러 무선 상태, GPS 사용, 디스플레이, Bluetooth)에서 데이터를 수집합니다. Energy Log는 앱의 어떤 작업이 가장 많은 배터리 소비를 유발하는지 보여주고 시간 축에 에너지 소비 그래프로 표시합니다.
도구는 에너지 소비 수준별로 작업을 분류합니다: 낮음(일반 프로세서 작업), 중간(Wi-Fi 전송), 높음(GPS, 모바일 네트워크, GPU). Energy Log가 오랜 시간 동안 높은 수준의 빨간색 표시기를 보여주면 — 앱이 백그라운드에서 배터리를 소모하고 있으며 사용자에 의해 제거될 것입니다.
Energy Log로 식별되는 일반적인 문제: 시간 제한 없는 WakeLock(작업 완료 후 프로세서를 활성 상태로 유지), 백그라운드에서 고정밀 Location Updates(몇 초마다 위치 요청), 네트워크 세션 이상(서버에 빈번한 재연결). Energy Log는 이러한 각 incident를 기록하고 에너지 집약적 작업을 중단하는 조건을 추가할 것을 권장합니다.
에너지 소비 테스트를 위해 배터리 전원의 실제 장치를 사용하세요 — 에뮬레이터에서는 에너지 소비 지표가 부정확합니다. CI에서 배터리 소비 확인을 자동화하려면 UI 테스트와 함께 Energy Log를 실행하세요.
Instruments 실행은 Xcode에서 두 가지 방법으로 수행됩니다: Product → Profile(⌘I) 메뉴를 통해 또는 Launchpad에서 별도 앱으로 Instruments를 열기. 첫 번째 방법이 더 편리합니다: Xcode가 자동으로 앱을 프로파일링 모드로 빌드하고 선택한 템플릿으로 연결된 장치에서 실행합니다. 세션 중지 후 Instruments는 .trace 확장자의 파일에 추적을 저장합니다.
결과 해석은 템플릿에 따라 다릅니다. Time Profiler의 경우 Self Weight 순으로 정렬된 Call Tree를 확인하세요 — 상위 메서드가 주요 병목 지점입니다. Allocations의 경우 — 순환 시나리오 후 # Living을 확인: 객체 수가 증가했다면 누수를 찾으세요. Leaks의 경우 — 빨간색 마커와 Cycles & Roots 그래프를 확인하세요. 최적화 전후 결과를 비교하세요 — 이것이 변경의 효과를 확인하는 유일한 방법입니다.
// CI용 Instruments 명령줄
// CI/CD 파이프라인에 Instruments 통합
import XCTest
class PerformanceTests: XCTestCase {
func testScrollPerformance() {
// 컬렉션 스크롤 시간 측정
measure(metrics: [XCTCPUMetric(), XCTMemoryMetric()]) {
app.scrollToBottom()
}
}
}
CI에서는 xcodebuild -showBuildSettings 및 xcrun xctrace를 통해 명령줄에서 Instruments를 실행할 수 있습니다. 이를 통해 커밋마다 프로파일링을 자동화하고 회귀를 놓치지 않을 수 있습니다. 분석에는 베이스라인 비교를 사용하세요: 메트릭이 이전 커밋보다 5% 악화된 경우 파이프라인이 중지되어야 합니다.
Instruments 작업 시 주요 오류: 장치 대신 시뮬레이터에서 프로파일링(CPU 및 GPU 데이터가 부정확), 시나리오 없이 데이터 수집(결과가 무작위), Call Tree 무시(특정 메서드가 아닌 그래프만 확인). 이러한 오류를 수정하면 프로파일링 품질의 80%를 얻을 수 있습니다.
자주 묻는 질문
네, Instruments는 SwiftUI를 완전히 지원합니다. UI 성능 분석에는 Core Animation 템플릿을 사용하세요 — 프레임 렌더링 속도를 표시하고 불필요한 View 재렌더링을 식별합니다. Time Profiler와 Allocations도 제한 없이 SwiftUI에서 작동합니다.
Instruments — CPU, 메모리, 네트워크, 그래픽 및 에너지 소비를涵盖하는 Apple 생태계 전체를 위한 범용 프로파일러입니다. Shark — Android의 메모리 누수 검색에 특화된 LeakCanary의 내부 힙 덤프 분석기입니다.
Instruments는 앱 코드에 내장되지 않습니다 — Xcode를 통해 실행 중인 프로세스에 연결되는 외부 도구입니다. 코드 변경이 필요하지 않습니다. .trace 파일은 바이너리에 포함되지 않는 단순 로그입니다.
표준 1ms 샘플링 속도에서 Time Profiler의 오버헤드는 3% 미만입니다. 정확한 추적 모드(함수 호출마다)에서는 오버헤드가 20~30%에 도달할 수 있으므로 일상적인 프로파일링에는 샘플링이 사용됩니다. 정확한 추적은 중요한 부분에만 필요합니다.
결과는 프로젝트 폴더의 .trace 파일에 자동으로 저장됩니다. 파일은 공동 분석을 위해 다른 Mac에서 Xcode로 열 수 있습니다. 텍스트 형식으로 내보내려면 xcrun xctrace export --input file.trace --output result.xml을 사용하세요.
요약
턴키 방식의 모바일 애플리케이션을 개발해 드립니다
IT Sectr는 2017년부터 스타트업과 기업을 위한 iOS 및 Android 애플리케이션을 만듭니다. 저희가 상담해 드리고 최적의 솔루션을 제안하겠습니다.