Heap Dump (dump ng heap) — isang snapshot ng dynamic na memorya ng application na naglalaman ng kumpletong impormasyon tungkol sa lahat ng buhay na bagay: kanilang mga klase, laki, mutual na mga referensya, at accessibility mula sa root nodes (GC roots). Heap Dump ang pangunahing kasangkapan sa pagsusuri ng mga memory leak at pag-optimize ng pagkonsumo ng resources. Ayon sa Android Developers, ang pagsusuri ng heap dumps ay nagbibigay-daan upang matukoy ang hanggang 95% ng mga memory leak, kabilang ang mga cyclical referensya, nakalimutang listener, at hindi nailabas na static na referensya.
Mga Pangunahing Punto
Heap dump ay isang kumpletong dump ng heap ng virtual machine — ang lugar ng memorya kung saan inilalagay ang lahat ng dynamic na nilikha na bagay. Sa Java at Kotlin ito ay Dalvik/ART sa Android, sa Swift at Objective-C — ang heap na pinamamahalaan ng ARC sa iOS. Ang heap dump ay nagtatala ng bawat bagay, klase nito, laki, field, referensya sa ibang bagay, at flag ng accessibility mula sa GC roots (stack variable, static field, JNI referensya).
Ang pangunahing layunin ng heap dump ay pagtuklas ng mga memory leak. Ang leak ay nangyayari kapag ang application ay patuloy na humahawak ng mga referensya sa mga bagay na hindi na kailangan, na pumipigil sa kanilang pagkolekta ng garbage collector (o pagpapalaya sa pamamagitan ng ARC). Mga karaniwang dahilan: event listener na hindi na-unregister sa pagkasira ng activity; singleton na may referensya sa context; closures na kumukuha ng self; static na koleksyon kung saan idinaragdag ang data nang hindi tinatanggal. Ang heap dump ay nagbibigay ng tumpak na larawan: aling mga bagay ang „buhay", alin ang sobra, at sino ang eksaktong tumutukoy sa kanila.
Ayon sa datos ng Google I/O, mahigit 60% ng crash reports ng Android application ay nauugnay sa OutOfMemoryError, at sa 80% ng mga kaso ang pangunahing dahilan ay memory leak na matutukoy sa pamamagitan ng heap dump. Para sa iOS application, ang sitwasyon ay katulad: ang mga leak dahil sa retain cycles ay isa sa mga karaniwang dahilan ng crash na natutukoy sa pamamagitan ng Allocations instrument sa Xcode.
Ang heap dump ay dapat gawin sa mga sumusunod na sintomas: ang application ay kumokonsumo ng memorya nang linear sa paulit-ulit na pagkilos (pag-navigate pabalik-balik sa pagitan ng mga screen); pagkatapos ng pagtatapos ng screen, ang memorya ay hindi bumabalik sa orihinal na antas; lumilitaw ang OutOfMemoryError o memory warning sa iOS; ang application ay nagte-terminate dahil sa paglampas sa limitasyon ng memorya (EXC_RESOURCE_RESOURCE sa iOS). Ang regular na pagkuha ng heap dumps ay bahagi ng protocol ng engineering culture sa malalaking mobile project tulad ng Instagram at Spotify.
Android Studio ay nagbibigay ng Memory Profiler — isang built-in na tool para sa pagkuha ng heap dump sa real-time. Maa-access sa pamamagitan ng View → Tool Windows → Profiler. Pagkatapos ilunsad ang application, pumili ng session, pumunta sa tab na Memory at i-click ang Dump Java Heap. I-pause ng Android Studio ang application, magsasagawa ng dump ng ART heap at ilo-load ang resulta para sa pagsusuri. Ang dump file ay may format na .hprof — HPROF standard na compatible sa karamihan ng memory analyzer.
Pagkatapos ma-load ang dump, ang Android Studio ay nagpapakita ng table ng mga bagay na may mga column: Allocations (bilang ng instances), Native Size (memorya sa labas ng ART heap), Shallow Size (memorya ng bagay mismo), Retained Size (memorya ng bagay kasama ang buong subgraph). Ang pag-filter ayon sa pangalan ng klase, pag-uuri ayon sa retained size, at paghahanap ayon sa package ay nagbibigay-daan upang mabilis na mahanap ang mga problemang lugar.
// Karaniwang leak — listener hindi na-unregister sa onDestroy
class MainActivity : AppCompatActivity() {
private val sensorManager by lazy {
getSystemService(SENSOR_SERVICE) as SensorManager
}
private val listener = MySensorListener()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
sensorManager.registerListener(listener,
sensorManager.getDefaultSensor(Sensor.TYPE_LIGHT),
SensorManager.SENSOR_DELAY_NORMAL)
}
override fun onDestroy() {
super.onDestroy()
// ❌ Hindi nasama ang sensorManager.unregisterListener(listener)
// → Activity hindi makokolekta ng GC, ipapakita ng heap dump ang leak
}
}
Ang tab na Dominator Tree ay nagpapakita ng mga bagay na humahawak ng pinakamaraming memorya. Kung ang isang bagay ay tinanggal mula sa dominator tree, ang lahat ng memorya na hawak nito ay magiging available para sa koleksyon. Ito ang pangunahing tool: sa halip na suriin ang libu-libong bagay, tumututok ka sa 10-20 bagay na kumokontrol ng 80-90% ng memorya. Ayon sa Google, ang pagsusuri ng dominator tree ay ang pinaka-epektibong paraan upang mahanap ang leak point, na binabawasan ang oras ng pagsusuri mula oras hanggang minuto.
Xcode Instruments ay nagbibigay ng dalawang tool para sa pagtatrabaho sa heap dump: Allocations — pagkuha ng dump ng heap na may graph ng konsumo sa real-time; Leaks — awtomatikong paghahanap ng mga leak sa pamamagitan ng pagsusuri ng retain cycles. Ang Allocations ay nagpapakita ng lahat ng bagay sa heap, kanilang laki, bilang ng paggawa (allocations) at pagpapalaya (deallocations). Ang pagkakaiba sa pagitan ng bilang ng paggawa at pagpapalaya para sa isang partikular na klase ay nagpapahiwatig ng potensyal na leak.
Ang pagkuha ng heap dump sa Allocations ay ginagawa gamit ang button na Snapshot Memory — pinipigilan ng tool ang application at kumukuha ng kumpletong dump. Pagkatapos nito, available ang mga standard view: listahan ng mga bagay ayon sa klase, call tree para sa bawat bagay, at report generator. Hindi tulad ng Android Studio, ang Xcode ay hindi gumagamit ng .hprof, kundi nag-iimbak ng data sa sarili nitong format na .trace, compatible sa Instruments.
// Karaniwang iOS leak — retain cycle sa pamamagitan ng closure
class NetworkManager {
var onComplete: ((Data) -> Void)?
func startRequest() {
// ❌ Kinukuha ng closure ang self — retain cycle
onComplete = { data in
self.process(data)
}
}
func process(_ data: Data) {}
}
Ang Leaks instrument ay awtomatikong detect ng retain cycles at mga leak sa pamamagitan ng pagsusuri ng referensya graph. Minamarkahan nito ang mga tumutulang bagay na may purple icon at nagpapakita ng path patungo sa root (GC root). Para ayusin ang retain cycle, sapat na magdagdag ng [weak self] o [unowned self] sa closure. Ang regular na pagpapatakbo ng Leaks instrument ay isang mandatoryong CI stage sa mga team na gumagamit ng Swift para sa iOS development.
// Ayos — mahinang referensya sa self
onComplete = { [weak self] data in
guard let self else { return }
self.process(data)
}
Para sa tamang pagsusuri ng heap dump, kailangang maunawaan ang tatlong pangunahing sukatan. Shallow size — ang dami ng memorya na direktang inookupahan ng bagay: mga field, header at alignment nito. Para sa isang tipikal na Java/Kotlin na bagay, ang shallow size ay 16-40 bytes. Retained size — ang shallow size ng bagay kasama ang kabuuang shallow size ng lahat ng bagay na maa-access lamang sa pamamagitan ng bagay na ito (iyon ay magiging basura kapag ito ay tinanggal). Ito ang retained size na nagpapakita ng tunay na epekto ng bagay sa pagkonsumo ng memorya.
| Sukatan | Paglalarawan | Halimbawa |
|---|---|---|
| Shallow size | Laki ng bagay mismo sa bytes | Bitmap (100×100) = 40 016 B |
| Retained size | Shallow size + lahat ng hawak nito | Activity na may View Tree = 2-5 MB |
| Deep size | Retained size + nested na bagay mula sa ibang graph | ScrollView na may adapter = 10-50 MB |
Dominator tree — isang structure kung saan ang bawat bagay ay tumutukoy sa kanyang „dominator" — ang bagay na kumokontrol sa accessibility nito. Kung ang dominator ay tinanggal, ang lahat ng bagay ng sub-tree nito ay magiging basura. Ang pagsusuri ng dominator tree ay ang pinakamabilis na paraan upang mahanap ang bagay na humahawak ng pinakamaraming memorya. Ayon sa Eclipse MAT (Memory Analyzer Tool), 90% ng mga leak ay natutukoy sa pamamagitan ng pagtingin sa top-20 dominator tree sa loob ng 5 minuto.
Ang proseso ng pagsusuri ng leak sa pamamagitan ng heap dump ay binubuo ng ilang hakbang. Hakbang 1: gawin ang aksyon na dapat magpalaya ng memorya (isara ang screen, tapusin ang operasyon). Hakbang 2: tawagan ang GC (System.gc() sa Android, forced snapshot sa Xcode) at gumawa ng heap dump. Hakbang 3: hanapin ang mga bagay na dapat na nawasak (halimbawa, isang instance ng Activity pagkatapos ng finish). Hakbang 4: para sa kahina-hinalang bagay, isagawa ang Path to GC Roots — ang chain ng referensya na nagpapanatiling buhay sa bagay. Ang huling referensya sa chain ay ang dahilan ng leak.
Ang function na Path to GC Roots ay available sa Android Studio Profiler, Eclipse MAT at Xcode Instruments. Ipinapakita nito ang pinakamaikling chain ng referensya mula GC root patungo sa problematikong bagay. Sa pagbubukod ng weak at soft referensya, makukuha mo lamang ang strong referensya — ang mga tunay na pumipigil sa koleksyon. Ayon sa statistics ng Square Engineering, 70% ng mga leak sa Android application ay sanhi ng dalawang pattern lamang: static na referensya sa Activity o Context at rehistradong ngunit hindi na-unregister na listener.
// Halimbawa ng leak sa pamamagitan ng static na referensya
object AppCache {
private val cache = mutableMapOf<String, Any>()
fun storeActivityReference(activity: Activity) {
cache["current_activity"] = activity // ❌ Leak!
}
}
// Ayos: mahinang referensya
object AppCacheFixed {
private val cache = mutableMapOf<String, WeakReference<Any>>()
}
Ang technique na comparison mode — isa sa pinaka-epektibong paraan ng paghahanap ng leak. Gumawa ng heap dump bago at pagkatapos ng paulit-ulit na aksyon (halimbawa, limang pag-navigate sa screen at pabalik). Ihambing ang bilang ng instances ng mga pangunahing klase: kung ang bilang ng Activity ay tumaas, kahit na ang lahat ng activity ay sarado — ito ay leak. Ang Android Studio at Eclipse MAT ay sumusuporta sa awtomatikong paghahambing ng dump na may pag-highlight ng mga pagkakaiba. Ayon sa Google, ang paghahambing ng dump ay nagbibigay-daan upang mahanap ang mga leak na hindi nakikita sa isang beses na pagsusuri dahil sa akumulasyon ng epekto.
Batay sa pagsusuri ng heap dump sa totoong proyekto, binuo ang mga napatunayang praktika ng pag-optimize ng memorya. Gamitin ang WeakReference para sa cache, callback, at referensya sa context sa mahabang buhay na bagay. I-unregister ang listener sa onPause/onDestroy para sa Android at deinit para sa iOS. Iwasan ang malalaking static na koleksyon — kung kinakailangan, gamitin ang LruCache na may limitasyon sa laki. I-optimize ang Bitmap: mag-load ng mga imahe na may tamang inSampleSize, gumamit ng Glide o Picasso na may disk cache.
Isama ang regular na pagkuha ng heap dump sa CI. I-configure ang task na nagpapatakbo ng instrumented UI test, nagsasagawa ng mga pangunahing user scenario, at naghahambing ng heap dump sa baseline. Kung ang retained size ay tumaas ng higit sa 5% mula sa baseline, ang build ay minarkahan bilang regression. Ang approach na ito ay isinasagawa sa Airbnb, Uber at iba pang kumpanya na may mataas na pangangailangan sa kalidad. Ayon sa Uber Engineering, ang pagpapatupad ng awtomatikong pagsusuri ng heap dump sa CI ay nagbawas ng bilang ng memory-related bugs ng 70% sa isang quarter.
// Halimbawa ng Gradle task para sa awtomatikong heap dump sa CI
task profileMemory(type: Exec) {
commandLine 'adb', 'shell',
'am start -n com.example/.MainActivity'
// Naghihintay ng pag-load
doLast {
exec { commandLine 'adb', 'shell',
'am broadcast -a com.example.DUMP_HEAP' }
}
}
Mga Madalas Itanong
Shallow size — laki ng bagay mismo (field + header). Retained size — laki ng bagay kasama ang lahat ng bagay na magiging basura kapag tinanggal ito. Ang retained size ang pangunahing indicator ng epekto ng bagay sa pagkonsumo ng memorya.
Sa pamamagitan ng Android Studio Profiler piliin ang device at proseso, i-click ang Dump Java Heap. Alternatibo — sa pamamagitan ng command line: adb shell am dumpheap PID /sdcard/dump.hprof, pagkatapos ay adb pull.
Ang heap dump ay sumasaklaw sa lahat ng buhay na bagay. Kung ang application ay gumagamit ng cache, Bitmap, o nagpoproseso ng malalaking data, ang dump ay maaaring umabot sa daan-daang megabyte. Mag-filter ayon sa klase o gumamit ng Eclipse MAT para i-load lamang ang index.
Oo, gamitin ang Eclipse MAT (Memory Analyzer Tool) — isang libreng tool para sa pagsusuri ng .hprof. Sumusuporta sa dominator tree, path to GC roots, paghahambing ng dump, at awtomatikong paghahanap ng leak sa pamamagitan ng Leak Suspects Report.
Ang dump mismo — oo, dahil ang pagkuha ng dump ay pumipigil sa lahat ng threads (stop-the-world). Walang dump — hindi. Gumawa ng dump sa kontroladong kondisyon (test environment, CI), hindi sa produksyon.
Buod
Gagawa kami ng mobile application na turnkey
Gumagawa ang IT Sectr ng mga iOS at Android application para sa mga startup at negosyo mula noong 2017. Magpapayo kami sa iyo at magmumungkahi ng pinakamahusay na solusyon.
Basahin din