Instruments — یک پروفایلر داخلی در Xcode برای تحلیل عملکرد برنامههای iOS، macOS، tvOS و watchOS است. این ابزار مجموعهای از قالبها برای اندازهگیری CPU، حافظه، شبکه، گرافیک و مصرف انرژی در زمان واقعی ارائه میدهد. به گفته Apple Developer Documentation، Instruments در تمام مراحل توسعه — از جستجوی نشت حافظه تا بهینهسازی زمان راهاندازی برنامه استفاده میشود.
نکات اصلی
Instruments — یک سیستم پروفایل و ردیابی است که بخشی از Xcode بوده و بر اساس فناوری DTrace توسعهیافته توسط Sun Microsystems ساخته شده است. Instruments دهها ابزار پروفایل (قالب) را در یک رابط واحد ترکیب میکند: کافی است قالبی را انتخاب کنید، برنامه را از طریق Xcode اجرا کنید و جمعآوری داده را شروع کنید.
معماری Instruments بر اساس مدل مشتری-سرور ساخته شده است: عامل روی دستگاه دادهها را جمعآوری کرده و از طریق اتصال USB به Mac ارسال میکند. این کار تأثیر پروفایلر بر عملکرد برنامه را به حداقل میرساند — Instruments عمدتاً در سمت میزبان کار میکند. بر اساس WWDC 2022، سربار Time Profiler در فرکانس نمونهبرداری 1 میلیثانیه کمتر از 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 — درخت فراخوانی مرتبشده بر اساس Self Weight نمایش داده میشود.
معیار کلیدی 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 از آستانه 16 میلیثانیه در هر فریم فراتر رود — UI کند خواهد شد. راهحل چنین مشکلاتی — انتقال رمزگشایی تصاویر، محاسبات layout و پردازش دادهها از نخ اصلی به پسزمینه از طریق Grand Central Dispatch (GCD) است.
Call Tree — نمایش سلسلهمراتبی تمام فراخوانیهای روشها، مرتبشده بر اساس Self Weight است. سنگینترین روش در Call Tree — اولین سطر است. با باز کردن سطر، میبینید کدام روشهای فرزند توسط این روش فراخوانی شدهاند و چقدر زمان گرفتهاند. به دنبال روشهایی بگردید که Self Weight (زمان خود) به طور قابل توجهی بیشتر از Weight (زمان کل) است — این نشانههای قفلهای همزمان و انتظار است.
Allocations — ابزاری برای نظارت بر تمام تخصیصهای حافظه برنامه است. نشان میدهد چه اشیایی، در چه مقداری و با چه اندازه کلی در هر لحظه ایجاد میشوند. برخلاف Memory Profiler در Android Studio، Allocations از Heapshot — عکس فوری از اشیای زنده با امکان مقایسه دو عکس پشتیبانی میکند.
رابط Allocations از دو بخش اصلی تشکیل شده است: All Allocations (آمار تجمعی بر اساس همه انواع اشیا) و Call Trees (درخت فراخوانی با تفکیک بر اساس روشهایی که اشیا را ایجاد میکنند). برای جستجوی نشت از Heapshot Analysis استفاده کنید: قبل از اجرای سناریو عکس بگیرید، سناریو را اجرا کنید، بعد از آن عکس بگیرید — و مقایسه کنید کدام اشیای جدید در حافظه باقی ماندهاند.
بر اساس Apple Developer Documentation، رایجترین الگوی نشت قابل شناسایی از طریق Allocations — ایجاد بیش از حد UIView و CALayer هنگام اسکرول مجموعهها است. اگر با هر اسکرول تعداد UIViewهای زنده افزایش یابد، در حالی که مجموعه از سلولها مجدداً استفاده میکند — جایی viewهای اضافی بدون آزادسازی viewهای قدیمی ایجاد میشوند. Allocations پشته فراخوانی دقیق محل ایجاد این viewها را نشان میدهد.
| پارامتر | توضیحات | به چه چیزی توجه کنیم |
|---|---|---|
| # Living | تعداد اشیای زنده از این نوع | باید در تکرار سناریو پایدار باشد |
| # Transient | اشیای ایجاد و آزاد شده در طول دوره | افزایش ناگهانی — نشانه تخصیصهای بیش از حد |
| Total Bytes | حجم کل حافظه این نوع | با RAM کل قابل دسترس دستگاه مقایسه کنید |
Heapshot — یک عکس فوری از اشیای زنده در Allocations است. قبل از اجرای سناریو Heapshot بگیرید، سناریو را اجرا کنید و Heapshot دوم را بگیرید. تفاوت بین عکسها نشان خواهد داد کدام اشیا ایجاد شده و آزاد نشدهاند. نتیجه ایدهآل — افزایش فقط اشیای موقت (Autorelease pool). برای تحلیل دقیق از ترکیب Allocations + Leaks در یک جلسه استفاده کنید. Allocations نشان میدهد کدام اشیا آزاد نمیشوند، و Leaks — چرا (کدام ارجاع قوی آنها را نگه میدارد). در هر ظن به نشت، جلسه دوگانه اجرا کنید.
Leaks — ابزاری تخصصی برای تشخیص نشت حافظه در برنامههای iOS و macOS است. برخلاف Allocations که صرفاً تخصیصها را نشان میدهد، Leaks به طور فعال heap را برای یافتن retain cycles — وضعیتهایی که دو یا چند شیء متقابلاً یکدیگر را با ارجاعات قوی نگه میدارند، اسکن میکند.
Leaks در ارتباط با Cycles & Roots — مصورساز گراف نگهداشت اشیا کار میکند. هنگامی که نشت تشخیص داده میشود، Leaks تمام اشیای موجود در چرخه، retain count آنها و فیلدهای دقیقی که ارجاعات از طریق آنها منتقل میشوند را نشان میدهد. توسعهدهنده فقط باید به گراف نگاه کند و بفهمد کدام ارجاع باید با weak جایگزین شود.
این ابزار به طور خودکار نشتها را با نشانگر قرمز روی خط زمانی مشخص میکند. Leaks در زمان واقعی کار میکند: به محض اینکه سیستم نشتی را تشخیص میدهد، بلافاصله به توسعهدهنده اعلام میکند. این امکان را میدهد که مشکلات را در محل برطرف کرد، بدون انتظار برای تخلیه و تحلیل پس از رویداد.
بر اساس WWDC 2022، Leaks قادر به تشخیص حتی retain cycles پیچیده چندسطحی — به عنوان مثال، زمانی که سه یا چند شیء یک زنجیره بسته از ارجاعات قوی تشکیل میدهند، میباشد. برای تشخیص چنین چرخههایی، گراف Cycles & Roots ضروری است: به صورت بصری نشان میدهد که اشیا چگونه به یکدیگر متصل میشوند.
هر گره گراف یک شیء است، هر پیکان — یک ارجاع قوی. چرخه — یک کانتور بسته از پیکانها است. رنگ گره وضعیت را نشان میدهد: قرمز — شیء نشتی، سبز — ریشه (GC Root)، خاکستری — شیء میانی. برای رفع نشت، پیکانی را پیدا کنید که میتوان بدون نقض منطق آن را weak کرد — و نوع ارجاع را در کد تغییر دهید.
Energy Log — قالبی از Instruments برای اندازهگیری مصرف انرژی برنامه است. دادهها را از سنسورهای سختافزاری دستگاه جمعآوری میکند: بار CPU، وضعیت Wi-Fi و شبکه سلولی، استفاده از GPS، نمایشگر و Bluetooth. Energy Log نشان میدهد کدام عملیات در برنامه بیشترین مصرف باتری را دارند و آنها را بر روی نمودار مصرف انرژی در مقیاس زمانی قرار میدهد.
این ابزار عملیات را بر اساس سطح مصرف انرژی طبقهبندی میکند: پایین (کار معمولی پردازنده)، متوسط (انتقال Wi-Fi)، بالا (GPS، شبکه موبایل، GPU). اگر Energy Log نشانگرهای قرمز سطح بالا را برای مدت طولانی نشان دهد — برنامه باتری را در پسزمینه تخلیه کرده و توسط کاربر حذف خواهد شد.
مشکلات معمول قابل تشخیص توسط Energy Log: WakeLock بدون محدودیت زمانی (برنامه پس از اتمام وظیفه پردازنده را فعال نگه میدارد)، بهروزرسانی موقعیت با دقت بالا در پسزمینه (هر چند ثانیه یک بار درخواست مختصات)، ناهنجاریهای جلسات شبکه (اتصال مجدد مکرر به سرور). Energy Log توصیه میکند هر چنین حادثهای را ثبت کرده و شرطی برای خاموش کردن عملیات انرژیبر اضافه کنید.
برای تست مصرف انرژی از دستگاه واقعی با تغذیه باتری استفاده کنید — در شبیهساز، شاخصهای مصرف انرژی نادرست هستند. Energy Log را همراه با تستهای UI برای خودکارسازی بررسی مصرف باتری در CI اجرا کنید.
اجرای Instruments از Xcode به دو صورت انجام میشود: از طریق منوی Product → Profile (⌘I) یا از طریق باز کردن Instruments به عنوان یک برنامه جداگانه در Launchpad. روش اول راحتتر است: Xcode به طور خودکار برنامه را در حالت پروفایل میسازد و آن را روی دستگاه متصل با قالب انتخاب شده اجرا میکند. پس از توقف جلسه، Instruments ردیابی را در فایلی با پسوند .trace ذخیره میکند.
تفسیر نتایج به قالب بستگی دارد. برای Time Profiler به Call Tree مرتبشده بر اساس Self Weight نگاه کنید — روشهای بالاترین تنگناهای اصلی شما هستند. برای Allocations — به # Living پس از سناریوی چرخهای: اگر تعداد اشیا افزایش یافته، به دنبال نشت بگردید. برای Leaks — به نشانگرهای قرمز و گراف Cycles & Roots. نتایج قبل و بعد از بهینهسازی را مقایسه کنید — این تنها راه تأیید کارایی تغییرات است.
// خط فرمان برای Instruments در CI
// ادغام Instruments در pipeline CI/CD
import XCTest
class PerformanceTests: XCTestCase {
func testScrollPerformance() {
// زمان اسکرول مجموعه را اندازهگیری میکنیم
measure(metrics: [XCTCPUMetric(), XCTMemoryMetric()]) {
app.scrollToBottom()
}
}
}
در CI میتوان Instruments را از خط فرمان از طریق xcodebuild -showBuildSettings و xcrun xctrace اجرا کرد. این امکان را میدهد که پروفایل را در هر commit خودکار کرده و رگرسیون را از دست ندهید. برای تحلیل از مقایسه Baseline استفاده کنید: اگر معیار نسبت به commit قبلی 5% بدتر شده باشد، pipeline باید متوقف شود.
اشتباهات اصلی هنگام کار با Instruments: پروفایل روی شبیهساز به جای دستگاه (دادههای CPU و GPU نادرست هستند)، جمعآوری داده بدون سناریو (نتایج تصادفی هستند)، نادیده گرفتن Call Tree (نگاه کردن فقط به نمودار، نه به روشهای خاص). رفع این اشتباهات 80% از کیفیت پروفایل را تأمین میکند.
سوالات متداول
بله، Instruments به طور کامل از SwiftUI پشتیبانی میکند. برای تحلیل عملکرد UI از قالب Core Animation استفاده کنید — سرعت رندر فریمها را نشان میدهد و بازترسیمهای اضافی View را شناسایی میکند. Time Profiler و Allocations نیز بدون محدودیت با SwiftUI کار میکنند.
Instruments — یک پروفایلر جهانی برای کل اکوسیستم Apple است که CPU، حافظه، شبکه، گرافیک و مصرف انرژی را پوشش میدهد. Shark — یک تحلیلگر داخلی heap dump در LeakCanary است که منحصراً در یافتن نشت حافظه در Android تخصص دارد.
Instruments در کد برنامه جاسازی نمیشود — این یک ابزار خارجی است که از طریق Xcode به فرآیند در حال اجرا متصل میشود. نیازی به اعمال هیچ تغییری در کد نیست. فایلهای .trace فقط لاگ هستند که وارد باینری نمیشوند.
در فرکانس نمونهبرداری استاندارد 1 میلیثانیه، سربار Time Profiler کمتر از 3% است. در حالت ردیابی دقیق (هر فراخوانی تابع) سربار میتواند به 20-30% برسد، بنابراین برای پروفایل روزمره از نمونهبرداری استفاده میشود. ردیابی دقیق فقط برای بخشهای حیاتی لازم است.
نتایج به طور خودکار در فایل .trace در پوشه پروژه ذخیره میشوند. فایل را میتوان در Mac دیگری با Xcode برای تحلیل مشترک باز کرد. برای صدور در قالب متنی از xcrun xctrace export --input file.trace --output result.xml استفاده کنید.
خلاصه
ما یک اپلیکیشن موبایل به صورت کلید در دست توسعه خواهیم داد
IT Sectr از سال 2017 برنامههای iOS و Android را برای استارتاپها و کسبوکارها ایجاد میکند. ما به شما مشاوره میدهیم و بهترین راهحل را پیشنهاد خواهیم کرد.
همچنین بخوانید