dumpsys هي أداة تعمل على أجهزة Android وتوفّر معلومات حول خدمات النظام. يمكنك استدعاء dumpsys من سطر الأوامر باستخدام
Android Debug Bridge (ADB)
للحصول على ناتج بيانات التشخيص لجميع خدمات النظام التي تعمل على جهاز متصل.
عادةً ما يكون هذا الناتج أكثر تفصيلاً مما تريد، لذا استخدِم خيارات سطر الأوامر في هذه الصفحة للحصول على الناتج الخاص بخدمات النظام التي تريدها فقط. توضّح هذه الصفحة أيضًا كيفية استخدام dumpsys لإنجاز المهام الشائعة، مثل فحص بيانات الإدخال أو ذاكرة الوصول العشوائي أو البطارية أو بيانات تشخيص الشبكة.
البنية
بناء الجملة العام لاستخدام dumpsys هو كما يلي:
adb shell dumpsys [-t timeout] [--help | -l | --skip services | service [arguments] | -c | -h]
للحصول على ناتج تشخيصي لجميع خدمات النظام على جهازك المتصل، شغِّل adb shell dumpsys.
ومع ذلك، ينتج عن ذلك معلومات أكثر بكثير مما قد تريده عادةً. للحصول على ناتج أسهل في الإدارة، حدِّد الخدمة التي تريد فحصها من خلال تضمينها في الأمر. على سبيل المثال، يوفّر الأمر أدناه بيانات النظام لمكوّنات الإدخال، مثل شاشات اللمس أو لوحات المفاتيح المدمَجة:
adb shell dumpsys input
للحصول على قائمة كاملة بخدمات النظام التي يمكنك استخدامها مع dumpsys، استخدِم الأمر التالي:
adb shell dumpsys -l
خيارات سطر الأوامر
يسرد الجدول التالي الخيارات المتاحة عند استخدام dumpsys:
الجدول 1. قائمة بالخيارات المتاحة لأداة dumpsys
| Option | الوصف |
|---|---|
-t timeout
|
حدِّد مدة المهلة بالثواني. إذا لم يتم تحديدها، تكون القيمة التلقائية 10 ثوانٍ. |
--help
|
اطبع نص المساعدة الخاص بالأداة dumpsys.
|
-l
|
أخرِج قائمة كاملة بخدمات النظام التي يمكنك استخدامها مع
dumpsys.
|
--skip services
|
حدِّد services التي لا تريد تضمينها في الناتج. |
service [arguments]
|
حدِّد service الذي تريد إخراجه. قد تتيح لك بعض الخدمات تمرير arguments اختيارية. للتعرّف على هذه الوسيطات الاختيارية، مرِّر الخيار -h مع الخدمة:
adb shell dumpsys procstats -h
|
-c
|
عند تحديد خدمات معيّنة، أضِف هذا الخيار لعرض البيانات بتنسيق مناسب للآلة. |
-h
|
بالنسبة إلى خدمات معيّنة، أضِف هذا الخيار للاطّلاع على نص المساعدة والخيارات الإضافية لهذه الخدمة. |
فحص بيانات التشخيص الخاصة بالإدخال
يؤدي تحديد خدمة input، كما هو موضّح في الأمر التالي، إلى تفريغ حالة أجهزة الإدخال في النظام، مثل لوحات المفاتيح وشاشات اللمس، ومعالجة أحداث الإدخال.
adb shell dumpsys input
تختلف النتيجة حسب إصدار Android الذي يعمل على الجهاز المتصل. توضّح الأقسام التالية نوع المعلومات التي تظهر لك عادةً.
حالة مركز الأحداث
في ما يلي مثال على ما قد يظهر لك عند فحص حالة "مركز الأحداث" في بيانات التشخيص الخاصة بالإدخال:
INPUT MANAGER (dumpsys input)
Event Hub State:
BuiltInKeyboardId: -2
Devices:
-1: Virtual
Classes: 0x40000023
Path:
Descriptor: a718a782d34bc767f4689c232d64d527998ea7fd
Location:
ControllerNumber: 0
UniqueId:
Identifier: bus=0x0000, vendor=0x0000, product=0x0000, version=0x0000
KeyLayoutFile: /system/usr/keylayout/Generic.kl
KeyCharacterMapFile: /system/usr/keychars/Virtual.kcm
ConfigurationFile:
HaveKeyboardLayoutOverlay: false
1: msm8974-taiko-mtp-snd-card Headset Jack
Classes: 0x00000080
Path: /dev/input/event5
Descriptor: c8e3782483b4837ead6602e20483c46ff801112c
Location: ALSA
ControllerNumber: 0
UniqueId:
Identifier: bus=0x0000, vendor=0x0000, product=0x0000, version=0x0000
KeyLayoutFile:
KeyCharacterMapFile:
ConfigurationFile:
HaveKeyboardLayoutOverlay: false
2: msm8974-taiko-mtp-snd-card Button Jack
Classes: 0x00000001
Path: /dev/input/event4
Descriptor: 96fe62b244c555351ec576b282232e787fb42bab
Location: ALSA
ControllerNumber: 0
UniqueId:
Identifier: bus=0x0000, vendor=0x0000, product=0x0000, version=0x0000
KeyLayoutFile: /system/usr/keylayout/msm8974-taiko-mtp-snd-card_Button_Jack.kl
KeyCharacterMapFile: /system/usr/keychars/msm8974-taiko-mtp-snd-card_Button_Jack.kcm
ConfigurationFile:
HaveKeyboardLayoutOverlay: false
3: hs_detect
Classes: 0x00000081
Path: /dev/input/event3
Descriptor: 485d69228e24f5e46da1598745890b214130dbc4
Location:
ControllerNumber: 0
UniqueId:
Identifier: bus=0x0000, vendor=0x0001, product=0x0001, version=0x0001
KeyLayoutFile: /system/usr/keylayout/hs_detect.kl
KeyCharacterMapFile: /system/usr/keychars/hs_detect.kcm
ConfigurationFile:
HaveKeyboardLayoutOverlay: false
...
حالة قارئ الإدخال
InputReader هو المسؤول عن فك ترميز أحداث الإدخال من النواة. تعرض عملية تفريغ الحالة معلومات حول كيفية ضبط كل جهاز إدخال والتغييرات الأخيرة التي حدثت في الحالة، مثل الضغطات على المفاتيح أو اللمسات على الشاشة التي تعمل باللمس.
يعرض المثال التالي الناتج لشاشة تعمل باللمس. دوِّن المعلومات المتعلّقة بدقة الجهاز ومَعلَمات المعايرة التي تم استخدامها.
Input Reader State
...
Device 6: Melfas MMSxxx Touchscreen
IsExternal: false
Sources: 0x00001002
KeyboardType: 0
Motion Ranges:
X: source=0x00001002, min=0.000, max=719.001, flat=0.000, fuzz=0.999
Y: source=0x00001002, min=0.000, max=1279.001, flat=0.000, fuzz=0.999
PRESSURE: source=0x00001002, min=0.000, max=1.000, flat=0.000, fuzz=0.000
SIZE: source=0x00001002, min=0.000, max=1.000, flat=0.000, fuzz=0.000
TOUCH_MAJOR: source=0x00001002, min=0.000, max=1468.605, flat=0.000, fuzz=0.000
TOUCH_MINOR: source=0x00001002, min=0.000, max=1468.605, flat=0.000, fuzz=0.000
TOOL_MAJOR: source=0x00001002, min=0.000, max=1468.605, flat=0.000, fuzz=0.000
TOOL_MINOR: source=0x00001002, min=0.000, max=1468.605, flat=0.000, fuzz=0.000
Touch Input Mapper:
Parameters:
GestureMode: spots
DeviceType: touchScreen
AssociatedDisplay: id=0, isExternal=false
OrientationAware: true
Raw Touch Axes:
X: min=0, max=720, flat=0, fuzz=0, resolution=0
Y: min=0, max=1280, flat=0, fuzz=0, resolution=0
Pressure: min=0, max=255, flat=0, fuzz=0, resolution=0
TouchMajor: min=0, max=30, flat=0, fuzz=0, resolution=0
TouchMinor: unknown range
ToolMajor: unknown range
ToolMinor: unknown range
Orientation: unknown range
Distance: unknown range
TiltX: unknown range
TiltY: unknown range
TrackingId: min=0, max=65535, flat=0, fuzz=0, resolution=0
Slot: min=0, max=9, flat=0, fuzz=0, resolution=0
Calibration:
touch.size.calibration: diameter
touch.size.scale: 10.000
touch.size.bias: 0.000
touch.size.isSummed: false
touch.pressure.calibration: amplitude
touch.pressure.scale: 0.005
touch.orientation.calibration: none
touch.distance.calibration: none
SurfaceWidth: 720px
SurfaceHeight: 1280px
SurfaceOrientation: 0
Translation and Scaling Factors:
XScale: 0.999
YScale: 0.999
XPrecision: 1.001
YPrecision: 1.001
GeometricScale: 0.999
PressureScale: 0.005
SizeScale: 0.033
OrientationCenter: 0.000
OrientationScale: 0.000
DistanceScale: 0.000
HaveTilt: false
TiltXCenter: 0.000
TiltXScale: 0.000
TiltYCenter: 0.000
TiltYScale: 0.000
Last Button State: 0x00000000
Last Raw Touch: pointerCount=0
Last Cooked Touch: pointerCount=0
في نهاية تفريغ حالة قارئ الإدخال، تظهر بعض المعلومات حول مَعلمات الإعدادات العامة، مثل فاصل النقر:
Configuration:
ExcludedDeviceNames: []
VirtualKeyQuietTime: 0.0ms
PointerVelocityControlParameters: scale=1.000, lowThreshold=500.000, highThreshold=3000.000, acceleration=3.000
WheelVelocityControlParameters: scale=1.000, lowThreshold=15.000, highThreshold=50.000, acceleration=4.000
PointerGesture:
Enabled: true
QuietInterval: 100.0ms
DragMinSwitchSpeed: 50.0px/s
TapInterval: 150.0ms
TapDragInterval: 300.0ms
TapSlop: 20.0px
MultitouchSettleInterval: 100.0ms
MultitouchMinDistance: 15.0px
SwipeTransitionAngleCosine: 0.3
SwipeMaxWidthRatio: 0.2
MovementSpeedRatio: 0.8
ZoomSpeedRatio: 0.3
حالة أداة توزيع الإدخال
يكون InputDispatcher مسؤولاً عن إرسال أحداث الإدخال إلى التطبيقات.
كما هو موضّح في نموذج الإخراج التالي، تعرض عملية تفريغ الحالة معلومات حول النافذة التي يتم لمسها وحالة قائمة انتظار الإدخال وما إذا كان خطأ ANR قيد التنفيذ ومعلومات أخرى عن أحداث الإدخال:
Input Dispatcher State:
DispatchEnabled: 1
DispatchFrozen: 0
FocusedApplication: <null>
FocusedWindow: name='Window{3fb06dc3 u0 StatusBar}'
TouchStates: <no displays touched>
Windows:
0: name='Window{357bbbfe u0 SearchPanel}', displayId=0, paused=false, hasFocus=false, hasWallpaper=false, visible=false, canReceiveKeys=false, flags=0x01820100, type=0x000007e8, layer=211000, frame=[0,0][1080,1920], scale=1.000000, touchableRegion=[0,0][1080,1920], inputFeatures=0x00000000, ownerPid=22674, ownerUid=10020, dispatchingTimeout=5000.000ms
1: name='Window{3b14c0ca u0 NavigationBar}', displayId=0, paused=false, hasFocus=false, hasWallpaper=false, visible=false, canReceiveKeys=false, flags=0x01840068, type=0x000007e3, layer=201000, frame=[0,1776][1080,1920], scale=1.000000, touchableRegion=[0,1776][1080,1920], inputFeatures=0x00000000, ownerPid=22674, ownerUid=10020, dispatchingTimeout=5000.000ms
2: name='Window{2c7e849c u0 com.vito.lux}', displayId=0, paused=false, hasFocus=false, hasWallpaper=false, visible=true, canReceiveKeys=false, flags=0x0089031a, type=0x000007d6, layer=191000, frame=[-495,-147][1575,1923], scale=1.000000, touchableRegion=[-495,-147][1575,1923], inputFeatures=0x00000000, ownerPid=4697, ownerUid=10084, dispatchingTimeout=5000.000ms
...
MonitoringChannels:
0: 'WindowManager (server)'
RecentQueue: length=10
MotionEvent(deviceId=4, source=0x00001002, action=2, flags=0x00000000, metaState=0x00000000, buttonState=0x00000000, edgeFlags=0x00000000, xPrecision=1.0, yPrecision=1.0, displayId=0, pointers=[0: (335.0, 1465.0)]), policyFlags=0x62000000, age=217264.0ms
MotionEvent(deviceId=4, source=0x00001002, action=1, flags=0x00000000, metaState=0x00000000, buttonState=0x00000000, edgeFlags=0x00000000, xPrecision=1.0, yPrecision=1.0, displayId=0, pointers=[0: (335.0, 1465.0)]), policyFlags=0x62000000, age=217255.7ms
MotionEvent(deviceId=4, source=0x00001002, action=0, flags=0x00000000, metaState=0x00000000, buttonState=0x00000000, edgeFlags=0x00000000, xPrecision=1.0, yPrecision=1.0, displayId=0, pointers=[0: (330.0, 1283.0)]), policyFlags=0x62000000, age=216805.0ms
...
PendingEvent: <none>
InboundQueue: <empty>
ReplacedKeys: <empty>
Connections:
0: channelName='WindowManager (server)', windowName='monitor', status=NORMAL, monitor=true, inputPublisherBlocked=false
OutboundQueue: <empty>
WaitQueue: <empty>
1: channelName='278c1d65 KeyguardScrim (server)', windowName='Window{278c1d65 u0 KeyguardScrim}', status=NORMAL, monitor=false, inputPublisherBlocked=false
OutboundQueue: <empty>
WaitQueue: <empty>
2: channelName='357bbbfe SearchPanel (server)', windowName='Window{357bbbfe u0 SearchPanel}', status=NORMAL, monitor=false, inputPublisherBlocked=false
OutboundQueue: <empty>
WaitQueue: <empty>
...
AppSwitch: not pending
7: channelName='2280455f com.google.android.gm/com.google.android.gm.ConversationListActivityGmail (server)', windowName='Window{2280455f u0 com.google.android.gm/com.google.android.gm.ConversationListActivityGmail}', status=NORMAL, monitor=false, inputPublisherBlocked=false
OutboundQueue: <empty>
WaitQueue: <empty>
8: channelName='1a7be08a com.android.systemui/com.android.systemui.recents.RecentsActivity (server)', windowName='Window{1a7be08a u0 com.android.systemui/com.android.systemui.recents.RecentsActivity EXITING}', status=NORMAL, monitor=false, inputPublisherBlocked=false
OutboundQueue: <empty>
WaitQueue: <empty>
9: channelName='3b14c0ca NavigationBar (server)', windowName='Window{3b14c0ca u0 NavigationBar}', status=NORMAL, monitor=false, inputPublisherBlocked=false
OutboundQueue: <empty>
WaitQueue: <empty>
...
Configuration:
KeyRepeatDelay: 50.0ms
KeyRepeatTimeout: 500.0ms
الأمور التي يجب التأكّد منها
في ما يلي قائمة بالأمور التي يجب مراعاتها عند فحص الناتج الخاص بخدمة input:
حالة "مركز الأحداث":
- تتوفّر جميع أجهزة الإدخال التي تتوقّعها.
- يحتوي كل جهاز إدخال على ملف تخطيط مفاتيح مناسب، وملف خريطة أحرف المفاتيح، وملف إعدادات جهاز الإدخال. إذا كانت الملفات غير متوفّرة أو تحتوي على أخطاء في البنية، لن يتم تحميلها.
- يتم تصنيف كل جهاز إدخال بشكل صحيح. تتطابق البتات في الحقل
Classesمع العلامات فيEventHub.h، مثلINPUT_DEVICE_CLASS_TOUCH_MT. - الرقم
BuiltInKeyboardIdصحيح. إذا لم يكن الجهاز مزوّدًا بلوحة مفاتيح مدمجة، يجب أن يكون المعرّف-2. وفي ما عدا ذلك، يجب أن يكون رقم تعريف لوحة المفاتيح المدمجة. - إذا لاحظت أنّ
BuiltInKeyboardIdليس-2ولكن من المفترض أن يكون كذلك، فهذا يعني أنّك تفتقد ملفًا أساسيًا لخريطة الأحرف الخاصة بلوحة مفاتيح ذات وظيفة خاصة. يجب أن تحتوي أجهزة لوحة المفاتيح ذات الوظائف الخاصة على ملفات خريطة أحرف المفاتيح التي تتضمّن السطرtype SPECIAL_FUNCTIONفقط.
أدخِل حالة القارئ:
- تتوفّر جميع أجهزة الإدخال المتوقّعة.
- تم ضبط كل جهاز إدخال بشكل صحيح. على وجه الخصوص، تحقَّق من صحة محاور شاشة اللمس وعصا التحكّم.
حالة أداة توزيع الإدخال:
- تتم معالجة جميع أحداث الإدخال على النحو المتوقّع.
- بعد لمس الشاشة وتشغيل
dumpsysفي الوقت نفسه، يحدّد السطرTouchStatesالنافذة التي تلمسها بشكل صحيح.
اختبار أداء واجهة المستخدم
يؤدي تحديد خدمة gfxinfo إلى توفير ناتج يتضمّن معلومات الأداء
المتعلّقة بإطارات الرسوم المتحركة التي تحدث أثناء مرحلة التسجيل.
يستخدم الأمر التالي gfxinfo لجمع بيانات أداء واجهة المستخدم الخاصة باسم حزمة محدّد:
adb shell dumpsys gfxinfo package-name
يمكنك أيضًا تضمين الخيار framestats لتقديم معلومات أكثر تفصيلاً حول توقيت اللقطات من اللقطات الحديثة، ما يتيح لك تتبُّع المشاكل وتصحيحها بدقة أكبر:
adb shell dumpsys gfxinfo package-name framestats
لمزيد من المعلومات حول استخدام gfxinfo وframestats لدمج قياسات أداء واجهة المستخدم في ممارسات الاختبار، راجِع مقالة كتابة اختبار Macrobenchmark.
فحص بيانات تشخيص الشبكة
يؤدي تحديد خدمة netstats إلى توفير إحصاءات استخدام الشبكة التي تم جمعها منذ آخر مرة تم فيها تشغيل الجهاز. لعرض معلومات إضافية، مثل معلومات مفصّلة عن المعرّف الفريد للمستخدم (UID)، أدرِج الخيار detail، كما يلي:
adb shell dumpsys netstats detail
تختلف النتيجة حسب إصدار Android الذي يعمل على الجهاز المتصل. توضّح الأقسام التالية نوع المعلومات التي تظهر لك عادةً.
الواجهات النشطة وواجهات معرّف المستخدم النشطة
تعرض عيّنة الإخراج التالية الواجهات النشطة وواجهات UID النشطة للجهاز المتصل. في معظم الحالات، تكون المعلومات الخاصة بالواجهات النشطة وواجهات UID النشطة متطابقة.
Active interfaces:
iface=wlan0 ident=[{type=WIFI, subType=COMBINED, networkId="Guest"}]
Active UID interfaces:
iface=wlan0 ident=[{type=WIFI, subType=COMBINED, networkId="Guest"}]
إحصاءات "Dev" و"Xt"
في ما يلي نموذج لمخرجات قسم "إحصاءات المطوّر":
Dev stats:
Pending bytes: 1798112
History since boot:
ident=[{type=WIFI, subType=COMBINED, networkId="Guest", metered=false}] uid=-1 set=ALL tag=0x0
NetworkStatsHistory: bucketDuration=3600
st=1497891600 rb=1220280 rp=1573 tb=309870 tp=1271 op=0
st=1497895200 rb=29733 rp=145 tb=85354 tp=185 op=0
st=1497898800 rb=46784 rp=162 tb=42531 tp=192 op=0
st=1497902400 rb=27570 rp=111 tb=35990 tp=121 op=0
Xt stats:
Pending bytes: 1771782
History since boot:
ident=[{type=WIFI, subType=COMBINED, networkId="Guest", metered=false}] uid=-1 set=ALL tag=0x0
NetworkStatsHistory: bucketDuration=3600
st=1497891600 rb=1219598 rp=1557 tb=291628 tp=1255 op=0
st=1497895200 rb=29623 rp=142 tb=82699 tp=182 op=0
st=1497898800 rb=46684 rp=160 tb=39756 tp=191 op=0
st=1497902400 rb=27528 rp=110 tb=34266 tp=120 op=0
إحصاءات رقم التعريف الفريد
في ما يلي عيّنة من الإحصاءات التفصيلية لكل معرّف فريد:
UID stats:
Pending bytes: 744
Complete history:
ident=[[type=MOBILE_SUPL, subType=COMBINED, subscriberId=311111...], [type=MOBILE, subType=COMBINED, subscriberId=311111...]] uid=10007 set=DEFAULT tag=0x0
NetworkStatsHistory: bucketDuration=7200000
bucketStart=1406167200000 activeTime=7200000 rxBytes=4666 rxPackets=7 txBytes=1597 txPackets=10 operations=0
ident=[[type=WIFI, subType=COMBINED, networkId="MySSID"]] uid=10007 set=DEFAULT tag=0x0
NetworkStatsHistory: bucketDuration=7200000
bucketStart=1406138400000 activeTime=7200000 rxBytes=17086802 rxPackets=15387 txBytes=1214969 txPackets=8036 operations=28
bucketStart=1406145600000 activeTime=7200000 rxBytes=2396424 rxPackets=2946 txBytes=464372 txPackets=2609 operations=70
bucketStart=1406152800000 activeTime=7200000 rxBytes=200907 rxPackets=606 txBytes=187418 txPackets=739 operations=0
bucketStart=1406160000000 activeTime=7200000 rxBytes=826017 rxPackets=1126 txBytes=267342 txPackets=1175 operations=35
للعثور على المعرّف الفريد لتطبيقك، نفِّذ الأمر التالي: adb shell dumpsys
package your-package-name. بعد ذلك، ابحث عن السطر الذي يحمل التصنيف
userId.
على سبيل المثال، للعثور على استخدام الشبكة للتطبيق "com.example.myapp"، شغِّل الأمر التالي:
adb shell dumpsys package com.example.myapp | grep userId
يجب أن يكون الناتج مشابهًا لما يلي:
userId=10007 gids=[3003, 1028, 1015]
باستخدام نموذج التفريغ السابق، ابحث عن الأسطر التي تحتوي على uid=10007. يتوفّر سطران من هذا النوع، يشير الأول إلى اتصال بشبكة الجوّال، ويشير الثاني إلى اتصال بشبكة Wi-Fi. أسفل كل سطر، يمكنك الاطّلاع على المعلومات التالية لكل فترة زمنية مدتها ساعتان، والتي bucketDuration تحدّد بالملّي ثانية:
- يشير
set=DEFAULTإلى استخدام الشبكة في المقدّمة، بينما يشيرset=BACKGROUNDإلى الاستخدام في الخلفية.set=ALLيشير إلى كليهما. - يشير
tag=0x0إلى علامة المقبس المرتبطة بعدد الزيارات. - يمثّل
rxBytesوrxPacketsعدد البايتات والحِزم المستلَمة في الفترة الزمنية المقابلة. - تمثّل
txBytesوtxPacketsالبايتات والحِزم التي تم إرسالها (نقلها) في الفترة الزمنية المقابلة.
فحص بيانات تشخيص البطارية
يؤدي تحديد الخدمة batterystats إلى إنشاء بيانات إحصائية حول استخدام البطارية على أحد الأجهزة، ويتم تنظيمها حسب معرّف المستخدم الفريد (UID). للتعرّف على كيفية استخدام dumpsys لاختبار تطبيقك للتأكّد من توافقه مع ميزتَي "قيلولة" و"تطبيقات وضع الاستعداد"، راجِع الاختبار باستخدام ميزتَي "قيلولة" و"تطبيقات وضع الاستعداد".
في ما يلي الأمر الخاص بـ batterystats:
adb shell dumpsys batterystats options
للاطّلاع على قائمة بالخيارات الإضافية المتاحة لـ batterystats، أدرِج الخيار -h. يعرض المثال التالي إحصاءات استخدام البطارية لحزمة تطبيق محدّدة منذ آخر مرة تم فيها شحن الجهاز:
adb shell dumpsys batterystats --charged package-name
يتضمّن الناتج عادةً ما يلي:
- سجلّ الأحداث المتعلّقة بالبطارية
- إحصاءات عامة للجهاز
- الاستخدام التقريبي للطاقة لكل معرّف UID ومكوّن نظام
- عدد الملّي ثانية لكل حزمة على الأجهزة الجوّالة لكل تطبيق
- إحصاءات مجمَّعة لمعرّف المستخدم في النظام
- إحصاءات مجمّعة حول المعرّف الفريد للتطبيق
لمزيد من المعلومات حول استخدام batterystats وإنشاء تمثيل مرئي بتنسيق HTML للناتج، ما يسهّل فهم المشاكل المتعلّقة بالبطارية وتشخيصها، يُرجى قراءة تحديد استخدام البطارية باستخدام أداتَي Batterystats وBattery Historian.
فحص الناتج المتوافق مع الآلات
يمكنك إنشاء نتائج batterystats بتنسيق CSV قابل للقراءة آليًا باستخدام الأمر التالي:
adb shell dumpsys batterystats --checkin
في ما يلي مثال على الناتج:
9,0,i,vers,11,116,K,L 9,0,i,uid,1000,android 9,0,i,uid,1000,com.android.providers.settings 9,0,i,uid,1000,com.android.inputdevices 9,0,i,uid,1000,com.android.server.telecom ... 9,0,i,dsd,1820451,97,s-,p- 9,0,i,dsd,3517481,98,s-,p- 9,0,l,bt,0,8548446,1000983,8566645,1019182,1418672206045,8541652,994188 9,0,l,gn,0,0,666932,495312,0,0,2104,1444 9,0,l,m,6794,0,8548446,8548446,0,0,0,666932,495312,0,697728,0,0,0,5797,0,0 ...
قد تكون ملاحظات استخدام البطارية على مستوى معرّف المستخدم أو على مستوى النظام. يتم اختيار البيانات لتضمينها استنادًا إلى مدى فائدتها في تحليل أداء البطارية. يمثّل كل صف ملاحظة، ويتضمّن العناصر التالية:
- عدد صحيح عنصر نائب
- رقم تعريف المستخدم المرتبط بالملاحظة
- وضع التجميع:
-
iللمعلومات غير المرتبطة بحالة الشحن/عدم الشحن lلمدة--charged(الاستخدام منذ آخر عملية شحن)-
uمقابل--unplugged(الاستخدام منذ آخر مرة تم فيها فصل الجهاز عن الشاحن) تم إيقافها نهائيًا في الإصدار 5.1.1 من نظام التشغيل Android.
-
- معرّف القسم، الذي يحدّد كيفية تفسير القيم اللاحقة في السطر
يوضّح الجدول التالي معرّفات الأقسام المختلفة التي قد تظهر لك:
الجدول 2. قائمة معرّفات الأقسام
| معرّف القسم | الوصف | الحقول المتبقية |
|---|---|---|
|
الإصدار |
|
|
الرقم التعريفي الفريد |
|
|
APK |
|
|
معالجة |
|
|
أداة استشعار |
|
|
هزاز |
|
|
واجهة |
|
|
توقيت الولاية |
|
|
قفل التنشيط |
|
|
المزامنة |
|
|
وظيفة |
|
|
قفل تنشيط النواة |
|
|
سبب التنشيط |
|
|
الشبكة |
|
|
نشاط المستخدم |
|
|
البطارية |
|
|
تفريغ شحن البطارية |
|
|
مستوى البطارية |
|
|
Wi-Fi |
|
|
شبكة Wi-Fi عالمية |
|
|
البلوتوث العالمي |
|
|
ميزات متنوّعة |
|
|
الشبكة العالمية |
|
|
سطوع الشاشة |
|
|
وقت فحص الإشارة |
|
|
وقت قوة الإشارة |
|
|
عدد قوة الإشارة |
|
|
مدة اتصال البيانات |
|
|
عدد اتصالات البيانات |
|
|
وقت حالة شبكة Wi-Fi |
|
|
عدد حالات شبكة Wi-Fi |
|
|
وقت حالة طالب المصادقة في شبكة Wi-Fi |
|
|
عدد حالات Wi-Fi Supplicant |
|
|
وقت قوة إشارة Wi-Fi |
|
|
عدد مرات رصد قوة إشارة شبكة Wi-Fi |
|
|
وقت حالة البلوتوث |
|
|
عدد حالات البلوتوث |
|
|
ملخّص استخدام الطاقة |
|
|
عنصر استخدام الطاقة |
|
|
خطوة إخلاء المسؤولية |
|
|
خطوة تحصيل الرسوم |
|
|
الوقت المتبقي للتفريغ |
|
|
وقت الشحن المتبقي |
|
ملاحظة: قبل الإصدار 6.0 من نظام التشغيل Android، كان يتم تتبُّع استخدام الطاقة لجهاز البلوتوث اللاسلكي والجهاز اللاسلكي للشبكة الخلوية وشبكة Wi-Fi في فئة القسم m (متنوعة). في الإصدار 6.0 من نظام التشغيل Android والإصدارات الأحدث، يتم تتبُّع استهلاك الطاقة لهذه المكوّنات في قسم pwi (عنصر استخدام الطاقة) مع تصنيفات فردية (wifi وblue وcell) لكل مكوّن.
عرض عمليات تخصيص الذاكرة
يمكنك فحص استخدام الذاكرة لتطبيقك بإحدى طريقتَين: على مدار فترة زمنية باستخدام procstats أو في وقت معيّن باستخدام meminfo.
توضّح لك الأقسام التالية كيفية استخدام كلتا الطريقتَين.
procstats
تتيح لك procstats معرفة سلوك تطبيقك بمرور الوقت،
بما في ذلك مدة تشغيله في الخلفية ومقدار الذاكرة التي يستخدمها خلال
هذه المدة. تساعدك هذه الأداة في العثور بسرعة على أوجه القصور والسلوكيات غير المرغوب فيها في تطبيقك، مثل تسربات الذاكرة، التي يمكن أن تؤثر في أدائه، خاصةً عند تشغيله على الأجهزة ذات الذاكرة المنخفضة. تعرض عملية تفريغ الحالة إحصاءات حول وقت تشغيل كل تطبيق، وحجم المجموعة المتناسبة (PSS)، وحجم المجموعة الفريدة (USS)، وحجم المجموعة المقيم (RSS).
للحصول على إحصاءات حول استخدام ذاكرة التطبيق خلال آخر ثلاث ساعات بتنسيق قابل للقراءة، شغِّل الأمر التالي:
adb shell dumpsys procstats --hours 3
كما هو موضّح في المثال التالي، يعرض الناتج النسبة المئوية
للمدة التي كان التطبيق يعمل فيها، بالإضافة إلى PSS وUSS وRSS
على شكل minPSS-avgPSS-maxPSS/minUSS-avgUSS-maxUSS/minRSS-avgRSS-maxRSS على
عدد العيّنات.
AGGREGATED OVER LAST 3 HOURS:
* com.android.systemui / u0a37 / v28:
TOTAL: 100% (15MB-16MB-17MB/7.7MB-8.7MB-9.4MB/7.7MB-9.6MB-84MB over 178)
Persistent: 100% (15MB-16MB-17MB/7.7MB-8.7MB-9.4MB/7.7MB-9.6MB-84MB over 178)
* com.android.se / 1068 / v28:
TOTAL: 100% (2.8MB-2.9MB-2.9MB/300KB-301KB-304KB/304KB-22MB-33MB over 3)
Persistent: 100% (2.8MB-2.9MB-2.9MB/300KB-301KB-304KB/304KB-22MB-33MB over 3)
* com.google.android.gms.persistent / u0a7 / v19056073:
TOTAL: 100% (37MB-38MB-40MB/27MB-28MB-29MB/124MB-125MB-126MB over 2)
Imp Fg: 100% (37MB-38MB-40MB/27MB-28MB-29MB/124MB-125MB-126MB over 2)
...
* com.android.gallery3d / u0a62 / v40030:
TOTAL: 0.01%
Receiver: 0.01%
(Cached): 54% (6.4MB-6.5MB-6.9MB/4.4MB-4.4MB-4.4MB/4.4MB-26MB-68MB over 6)
* com.google.android.tvlauncher / u0a30 / v1010900130:
TOTAL: 0.01%
Receiver: 0.01%
(Cached): 91% (5.8MB-13MB-14MB/3.5MB-10MB-12MB/12MB-33MB-78MB over 6)
* com.android.vending:instant_app_installer / u0a16 / v81633968:
TOTAL: 0.01%
Receiver: 0.01%
(Cached): 100% (14MB-15MB-16MB/3.8MB-4.2MB-5.1MB/3.8MB-30MB-95MB over 7)
...
Run time Stats:
SOff/Norm: +32m52s226ms
SOn /Norm: +2h10m8s364ms
Mod : +17s930ms
TOTAL: +2h43m18s520ms
Memory usage:
Kernel : 265MB (38 samples)
Native : 73MB (38 samples)
Persist: 262MB (90 samples)
Top : 190MB (325 samples)
ImpFg : 204MB (569 samples)
ImpBg : 754KB (345 samples)
Service: 93MB (1912 samples)
Receivr: 227KB (1169 samples)
Home : 66MB (12 samples)
LastAct: 30MB (255 samples)
CchAct : 220MB (450 samples)
CchCAct: 193MB (71 samples)
CchEmty: 182MB (652 samples)
Cached : 58MB (38 samples)
Free : 60MB (38 samples)
TOTAL : 1.9GB
ServRst: 50KB (278 samples)
Start time: 2015-04-08 13:44:18
Total elapsed time: +2h43m18s521ms (partial) libart.so
meminfo
يمكنك تسجيل لقطة من طريقة تقسيم ذاكرة تطبيقك بين أنواع مختلفة من تخصيص ذاكرة الوصول العشوائي (RAM) باستخدام الأمر التالي:
adb shell dumpsys meminfo [-d] package_name|pid
تعرض العلامة -d المزيد من المعلومات ذات الصلة باستخدام ذاكرة Dalvik وART.
تعرض العلامة -h جميع العلامات المتوافقة.
تعرض النتائج جميع عمليات التخصيص الحالية لتطبيقك، ويتم قياسها بالكيلوبايت.
عند فحص هذه المعلومات، يجب أن تكون على دراية بأنواع التخصيص التالية:
- ذاكرة الوصول العشوائي (RAM) النظيفة والمعدّلة الخاصة
- هذه هي الذاكرة التي يستخدمها تطبيقك فقط. وهي الجزء الأكبر من ذاكرة الوصول العشوائي (RAM) التي يمكن للنظام استردادها عند إيقاف عملية تطبيقك. بشكل عام، الجزء الأكثر أهمية من ذلك هو ذاكرة الوصول العشوائي الخاصة المعدّلة، وهي الأكثر تكلفة لأنّها تُستخدم فقط من خلال عمليتك ولأنّ محتوياتها توجد بشكل أساسي في ذاكرة الوصول العشوائي النشطة. على الرغم من أنّ نظام التشغيل Android يتجنّب ملفات التبديل التقليدية على القرص، إلا أنّه يستخدم zRAM (ضغط الصفحات في الذاكرة) لتبديل الصفحات غير النظيفة، كما يستخدم أحيانًا zRAM Writeback لتخزين الصفحات غير النشطة على ذاكرة الفلاش. ومع ذلك، بما أنّ ضغط الصفحات يستهلك دورات وحدة المعالجة المركزية (CPU)، ويتم تقييد عمليات الكتابة في ذاكرة الفلاش بشكل صارم لمنع تلف الأجهزة، لا يمكن إخلاء ذاكرة الوصول العشوائي (RAM) الخاصة غير النظيفة بدون تكلفة. جميع عمليات تخصيص الذاكرة المؤقتة الأصلية وذاكرة Dalvik المؤقتة التي تجريها هي ذاكرة وصول عشوائي (RAM) خاصة معدّلة. تكون عمليات تخصيص الذاكرة الأصلية وذاكرة Dalvik التي تشاركها مع عملية Zygote عبارة عن ذاكرة وصول عشوائي (RAM) مشترَكة غير نظيفة.
- حجم المجموعة المتناسب (PSS)
- هذا مقياس لاستخدام تطبيقك لذاكرة الوصول العشوائي (RAM) يأخذ في الاعتبار مشاركة الصفحات بين العمليات. تساهم أي صفحات RAM فريدة في عمليتك بشكل مباشر في قيمة PSS، بينما تساهم الصفحات التي تتم مشاركتها مع عمليات أخرى في قيمة PSS بما يتناسب مع مقدار المشاركة. على سبيل المثال، تساهم صفحة مشترَكة بين عمليتَين بنصف حجمها في مجموعة PSS لكل عملية.
من خصائص قياس PSS أنّه يمكنك جمع قيم PSS في جميع العمليات لتحديد مقدار الذاكرة الفعلي الذي تستخدمه جميع العمليات. وهذا يعني أنّ مقياس PSS هو مقياس جيد لوزن ذاكرة الوصول العشوائي (RAM) الفعلي لإحدى العمليات، كما أنّه مقياس جيد للمقارنة بين استخدام ذاكرة الوصول العشوائي (RAM) لعمليات أخرى وإجمالي ذاكرة الوصول العشوائي (RAM) المتاحة.
على سبيل المثال، ما يلي هو الناتج الخاص بعملية "خرائط Google" على جهاز Nexus 5:
adb shell dumpsys meminfo -d com.google.android.apps.maps
ملاحظة: قد تختلف المعلومات التي تظهر لك قليلاً عن المعلومات المعروضة هنا، لأنّ بعض تفاصيل الناتج تختلف باختلاف إصدارات المنصة.
** MEMINFO in pid 18227 [com.google.android.apps.maps] **
Pss Private Private Swapped Heap Heap Heap
Total Dirty Clean Dirty Size Alloc Free
------ ------ ------ ------ ------ ------ ------
Native Heap 10468 10408 0 0 20480 14462 6017
Dalvik Heap 34340 33816 0 0 62436 53883 8553
Dalvik Other 972 972 0 0
Stack 1144 1144 0 0
Gfx dev 35300 35300 0 0
Other dev 5 0 4 0
.so mmap 1943 504 188 0
.apk mmap 598 0 136 0
.ttf mmap 134 0 68 0
.dex mmap 3908 0 3904 0
.oat mmap 1344 0 56 0
.art mmap 2037 1784 28 0
Other mmap 30 4 0 0
EGL mtrack 73072 73072 0 0
GL mtrack 51044 51044 0 0
Unknown 185 184 0 0
TOTAL 216524 208232 4384 0 82916 68345 14570
Dalvik Details
.Heap 6568 6568 0 0
.LOS 24771 24404 0 0
.GC 500 500 0 0
.JITCache 428 428 0 0
.Zygote 1093 936 0 0
.NonMoving 1908 1908 0 0
.IndirectRef 44 44 0 0
Objects
Views: 90 ViewRootImpl: 1
AppContexts: 4 Activities: 1
Assets: 2 AssetManagers: 2
Local Binders: 21 Proxy Binders: 28
Parcel memory: 18 Parcel count: 74
Death Recipients: 2 OpenSSL Sockets: 2
في ما يلي إصدار قديم dumpsys على Dalvik من تطبيق Gmail:
** MEMINFO in pid 9953 [com.google.android.gm] **
Pss Pss Shared Private Shared Private Heap Heap Heap
Total Clean Dirty Dirty Clean Clean Size Alloc Free
------ ------ ------ ------ ------ ------ ------ ------ ------
Native Heap 0 0 0 0 0 0 7800 7637(6) 126
Dalvik Heap 5110(3) 0 4136 4988(3) 0 0 9168 8958(6) 210
Dalvik Other 2850 0 2684 2772 0 0
Stack 36 0 8 36 0 0
Cursor 136 0 0 136 0 0
Ashmem 12 0 28 0 0 0
Other dev 380 0 24 376 0 4
.so mmap 5443(5) 1996 2584 2664(5) 5788 1996(5)
.apk mmap 235 32 0 0 1252 32
.ttf mmap 36 12 0 0 88 12
.dex mmap 3019(5) 2148 0 0 8936 2148(5)
Other mmap 107 0 8 8 324 68
Unknown 6994(4) 0 252 6992(4) 0 0
TOTAL 24358(1) 4188 9724 17972(2)16388 4260(2)16968 16595 336
Objects
Views: 426 ViewRootImpl: 3(8)
AppContexts: 6(7) Activities: 2(7)
Assets: 2 AssetManagers: 2
Local Binders: 64 Proxy Binders: 34
Death Recipients: 0
OpenSSL Sockets: 1
SQL
MEMORY_USED: 1739
PAGECACHE_OVERFLOW: 1164 MALLOC_SIZE: 62
بشكل عام، يجب التركيز على العمودَين Pss Total وPrivate Dirty فقط.
في بعض الحالات، يقدّم العمودان Private Clean وHeap Alloc أيضًا بيانات مفيدة.
تقدّم المعلومات التالية تفاصيل أكثر حول عمليات تخصيص الذاكرة المختلفة التي يجب مراقبتها:
Dalvik Heap- ذاكرة الوصول العشوائي (RAM) التي تستخدمها عمليات تخصيص Dalvik في تطبيقك. يتضمّن
Pss Totalجميع عمليات تخصيص Zygote، مع مراعاة مشاركتها في العمليات، كما هو موضّح في تعريف PSS. رقمPrivate Dirtyهو مقدار ذاكرة الوصول العشوائي (RAM) المخصّصة فقط لمساحة التخزين المؤقت في تطبيقك، وهي تتألف من عمليات التخصيص الخاصة بك وأي صفحات تخصيص Zygote تم تعديلها منذ إنشاء نسخة من عملية تطبيقك من Zygote.ملاحظة: في إصدارات النظام الأساسي الأحدث التي تتضمّن القسم
Dalvik Other، لا يشمل الرقمَانPss TotalوPrivate Dirtyالخاصان بذاكرة Dalvik المؤقتة النفقات العامة لـ Dalvik، مثل الترجمة الفورية (JIT) وإدارة الذاكرة غير المستخدَمة، بينما تسرد الإصدارات القديمة كل ذلك مجمّعًا ضمنDalvik.
Heap Allocهو مقدار الذاكرة التي يتتبّعها كل من Dalvik وأدوات تخصيص الذاكرة الأصلية لتطبيقك. وتكون هذه القيمة أكبر منPss TotalوPrivate Dirtyلأنّ عمليتك تم تشعّبها من Zygote وتتضمّن عمليات تخصيص تشاركها عمليتك مع جميع العمليات الأخرى. .so mmapو.dex mmap- ذاكرة الوصول العشوائي المستخدَمة للرمز البرمجي
.so(المدمج مع المحتوى) و.dex(Dalvik أو ART) الذي تم ربطهما يتضمّن الرقمPss Totalرمز النظام الأساسي المشترك بين التطبيقات. Private Cleanهو الرمز الخاص بتطبيقك. بشكل عام، يكون الحجم الفعلي الذي تم ربطه أكبر. إنّ ذاكرة الوصول العشوائي (RAM) هنا هي فقط ما يجب أن يكون حاليًا في ذاكرة الوصول العشوائي (RAM) للرمز الذي تم تنفيذه بواسطة التطبيق. ومع ذلك، يحتوي.so mmapعلى مساحة كبيرة خاصة غير نظيفة، ويرجع ذلك إلى عمليات الإصلاح التي تم إجراؤها على الرمز البرمجي الأصلي عند تحميله إلى عنوانه النهائي. .oat mmap- هذا هو مقدار ذاكرة الوصول العشوائي (RAM) التي تستخدمها صورة الرمز. ويستند إلى الفئات المحمَّلة مسبقًا شائعة الاستخدام التي تستخدمها عدة تطبيقات. تتم مشاركة هذه الصورة في جميع التطبيقات ولا تتأثر بتطبيقات معيّنة.
.art mmap- هذا هو مقدار ذاكرة الوصول العشوائي (RAM) التي تستخدمها صورة الذاكرة المكدّسة. ويستند إلى الفئات المحمَّلة مسبقًا شائعة الاستخدام التي تستخدمها عدة تطبيقات. تتم مشاركة هذه الصورة بين جميع التطبيقات ولا تتأثّر بتطبيقات معيّنة. على الرغم من أنّ صورة ART تحتوي على
Objectمثيل، فإنّها لا تُحتسب ضمن حجم الذاكرة المؤقتة. -
.Heap(فقط مع العلامة-d) - هذا هو مقدار ذاكرة الكومة لتطبيقك، ويستثني هذا المقدار العناصر الموجودة في مساحات الصور والعناصر الكبيرة، ولكنه يتضمّن مساحة Zygote والمساحة غير المتحركة.
-
.LOS(فقط مع العلامة-d) - هذا هو مقدار ذاكرة الوصول العشوائي التي تستخدمها مساحة الكائنات الكبيرة في ART. ويشمل ذلك كائنات Zygote الكبيرة. جميع الكائنات الكبيرة هي عمليات تخصيص لمصفوفات أولية أكبر من 12 كيلوبايت.
-
.GC(فقط مع العلامة-d) - هذه هي التكلفة العامة لجمع البيانات المُهمَلة. وما مِن طريقة لتقليل هذا الحمل الزائد.
-
.JITCache(فقط مع العلامة-d) - هذا هو مقدار الذاكرة التي تستخدمها ذاكرات التخزين المؤقت للبيانات والرموز البرمجية التي يتم تجميعها في الوقت الفعلي. عادةً ما تكون القيمة صفرًا، لأنّه يتم تجميع جميع التطبيقات عند تثبيتها.
-
.Zygote(فقط مع العلامة-d) - هذا هو مقدار الذاكرة التي تستخدمها مساحة Zygote. يتم إنشاء مساحة Zygote أثناء بدء تشغيل الجهاز ولا يتم تخصيصها مطلقًا.
-
.NonMoving(فقط مع العلامة-d) - هذا هو مقدار ذاكرة الوصول العشوائي (RAM) التي تستخدمها مساحة ART غير المتحركة. تحتوي مساحة الذاكرة غير المتحركة على عناصر خاصة غير قابلة للنقل، مثل الحقول والطرق. يمكنك تقليل حجم هذا القسم باستخدام عدد أقل من الحقول والطرق في تطبيقك.
-
.IndirectRef(فقط مع العلامة-d) - هذا هو مقدار ذاكرة الوصول العشوائي (RAM) التي تستخدمها جداول المراجع غير المباشرة في ART. عادةً ما يكون هذا المقدار صغيرًا، ولكن إذا كان مرتفعًا جدًا، قد تتمكّن من تقليله عن طريق تقليل عدد مراجع JNI المحلية والعالمية المستخدَمة.
Unknown- أي صفحات RAM لم يتمكّن النظام من تصنيفها ضمن أي من العناصر الأخرى الأكثر تحديدًا في الوقت الحالي، يحتوي هذا القسم في الغالب على عمليات تخصيص أصلية لا يمكن للأداة تحديدها عند جمع هذه البيانات بسبب ميزة "توزيع عشوائي لتصميم مساحة العناوين" (ASLR). مثل مساحة الذاكرة المؤقتة في Dalvik، تأخذ
Pss TotalUnknownفي الاعتبار المشاركة مع Zygote، بينماPrivate Dirtyهي مقدار غير معروف من ذاكرة الوصول العشوائي المخصّصة لتطبيقك فقط. TOTAL- إجمالي ذاكرة الوصول العشوائي (RAM) التي تستخدمها العملية في "حجم المجموعة النسبية" (PSS). هذا هو مجموع جميع حقول PSS أعلاه. تشير هذه السمة إلى حجم الذاكرة الإجمالي للعملية، ويمكن مقارنتها مباشرةً بالعمليات الأخرى وإجمالي ذاكرة الوصول العشوائي المتاحة.
Private DirtyوPrivate Cleanهما إجمالي عمليات التخصيص ضمن العملية، ولا تتم مشاركتهما مع عمليات أخرى. عند إيقاف العملية، يتم تحرير كل ذاكرة الوصول العشوائي التي تم تخصيصها وإعادتها إلى النظام. يمكن أيضًا إخراجPrivate Cleanمن الذاكرة وتحريرها قبل إيقاف العملية، ولكن لا يتم تحريرPrivate Dirtyإلا عند إيقاف العملية.ذاكرة الوصول العشوائي (RAM) غير النظيفة هي صفحات تم تعديلها ويتم إما الاحتفاظ بها في ذاكرة الوصول العشوائي النشطة أو ضغطها في zRAM أو إعادة كتابتها إلى وحدة التخزين. ذاكرة الوصول العشوائي النظيفة هي صفحات تم ربطها بملف ثابت، مثل الرمز الذي يتم تنفيذه، ويمكن نقلها إلى الذاكرة الافتراضية إذا لم يتم استخدامها لفترة من الوقت.
ViewRootImpl- عدد طرق العرض الجذرية النشطة في عمليتك يرتبط كل عرض جذري بنافذة، لذا يمكن أن يساعدك ذلك في تحديد تسربات الذاكرة التي تتضمّن مربّعات حوار أو نوافذ أخرى.
AppContextsوActivities- عدد عناصر التطبيق
ContextوعناصرActivityالتي يتم تنفيذها حاليًا في عمليتك. يمكن أن يساعدك ذلك في تحديدActivityالكائنات التي تم تسريبها والتي لا يمكن جمعها كبيانات غير ضرورية بسبب المراجع الثابتة لها، وهو أمر شائع. وغالبًا ما تتضمّن هذه العناصر العديد من عمليات التخصيص الأخرى المرتبطة بها، ما يجعلها طريقة جيدة لتتبُّع تسرُّبات الذاكرة الكبيرة.