JS Closure Memory Leaks

နိဒါန်း

X မှာ closure ကြောင့် memory leak ဖြစ်တဲ့အကြောင်း status တစ်ခုတွေ့လိုက်လို့ အဲ့ဒီအကြောင်းနည်းနည်းပြောချင်ပါတယ်။ JavaScript မှာ event listener တွေနဲ့ arrow function တွေသုံးတဲ့အခါ memory leak ဖြစ်နိုင်တယ်။ ဒီ article မှာ memory leak ဖြစ်တဲ့အကြောင်းရင်းနဲ့ bind() method နဲ့ ဘယ်လိုဖြေရှင်းမလဲဆိုတာ အသေးစိတ်ပြောပြပေးပါမယ်။

Problem: Arrow Function နဲ့ Memory Leak

ပြဿနာရှိတဲ့ Code

Memory Leak ဖြစ်တဲ့အကြောင်းရင်း

Arrow function () => controller.abort() က closure တစ်ခု create လုပ်တယ်။ Closure က surrounding scope မှာရှိတဲ့ variable အားလုံးကို capture လုပ်ထားတယ်:

  • controller (AbortController instance)

  • this (surrounding context)

  • init (request initialization options)

  • options (potentially large objects)

  • Request body နဲ့ တခြား large object တွေ

Memory Leak Chain

၁. Signal က long-lived object ဖြစ်နေတယ်

  • AbortSignal တွေက မိနစ်တွေ၊ နာရီတွေအထိ live ဖြစ်နေနိုင်တယ်

၂. Event listener က arrow function ကို reference လုပ်ထားတယ်

  • Signal က listener ကို မဖျက်သရွေ့ arrow function က memory မှာ ရှိနေမယ်

၃. Arrow function ရဲ့ closure က variable အားလုံးကို hold လုပ်ထားတယ်

  • Closure က scope မှာရှိတဲ့ variable တိုင်းကို reference လုပ်ထားတယ်

၄. Request ပြီးသွားပြီးနောက်ပိုင်းမှာလည်း signal က live ဖြစ်နေသေးတယ်

  • User က AbortSignal ကို ကြာကြာ hold ထားနိုင်တယ်

၅. ရလဒ်: အရာအားလုံး memory မှာ stuck ဖြစ်နေတယ် 💥

  • Garbage collector က ဘာမှ ဖျက်မပစ်နိုင်ဘူး

  • Memory usage က တက်နေတယ်

Solution: bind() Method သုံးခြင်း

Fix လုပ်ပြီးသား Code

bind() က Memory Leak ကို ဘယ်လို fix လုပ်သလဲ

၁. Closure မလုပ်ဘူး

Bound function က:

  • controller ကိုပဲ reference လုပ်တယ် (via [[BoundThis]])

  • ✅ Surrounding scope ကို capture မလုပ်ဘူး

  • this, init, options တွေကို hold မထားဘူး

၂. { once: true } option

javascript

ဒီ option က:

  • Event fire ဖြစ်တာနဲ့ listener ကို auto remove လုပ်ပေးတယ်

  • Memory cleanup က ချက်ချင်း ဖြစ်တယ်

Technical အသေးစိတ်

Arrow Function vs Bound Function

❌ Arrow Function (Memory Leak ဖြစ်တယ်)

✅ Bound Function (Memory Leak မဖြစ်ဘူး)

Memory Footprint နှိုင်းယှဉ်ချက်

Scenario: Request 1000 ခု လုပ်တယ်

ECMAScript Specification အရ ဆိုရင်

Arrow Function Closure (§15.3.3)

Arrow function က lexical scoping သုံးတယ်:

၁. Function create လုပ်တဲ့အခါ:

  • Surrounding scope ရဲ့ environment record ကို capture လုပ်တယ်

  • Variable တွေရဲ့ reference ကို store လုပ်တယ်

၂. Function ကို call လုပ်တဲ့အခါ:

  • Captured environment ကို သုံးတယ်

  • Variable တွေကို original scope ကနေ read လုပ်တယ်

၃. Memory management:

  • Function က live ဖြစ်နေသရွေ့ environment က memory မှာ ရှိနေမယ်

  • Garbage collector က ဘာမှ delete မလုပ်နိုင်ဘူး

Bound Function (§20.2.3.2, §10.4.1)

bind() က exotic object တစ်ခု create လုပ်တယ်:

၁. bind() call လုပ်တဲ့အခါ:

javascript

Spec က ဒီလို လုပ်တယ်:

  • Target function ကို store လုပ်တယ် ([[BoundTargetFunction]])

  • thisArg ကို store လုပ်တယ် ([[BoundThis]])

  • Argument တွေကို store လုပ်တယ် ([[BoundArguments]])

  • Environment ကို capture မလုပ်ဘူး

၂. Bound function ကို call လုပ်တဲ့အခါ:

  • Store လုပ်ထားတဲ့ [[BoundThis]] ကို this အနေနဲ့ သုံးတယ်

  • Original function ကို call လုပ်တယ်

  • Normal this binding rules ကို ignore လုပ်တယ်

၃. Memory management:

  • [[BoundThis]] object ကိုပဲ reference လုပ်တယ်

  • တခြား variable တွေကို capture မလုပ်ဘူး

  • Memory footprint က သေးတယ်

Real-World ဥပမာ

Web Application: Fetch Requests

javascript

Performance Impact

Memory usage test:

javascript

Best Practices

၁. Long-lived Event Listener တွေမှာ bind() သုံးပါ

javascript

၂. { once: true } option ကို သုံးပါ

၃. Timer တွေမှာ bind() သုံးပါ

၄. Memory cleanup ကို သေချာ လုပ်ပါ

နိဂုံး

အဓိက Point တွေ

၁. Arrow function က closure create လုပ်တယ်

  • Surrounding scope မှာရှိတဲ့ variable အားလုံးကို capture လုပ်တယ်

  • Memory leak ဖြစ်စေနိုင်တယ်

၂. bind() က closure မ create ဘူး

  • this value ကိုပဲ bind လုပ်တယ်

  • Memory footprint က သေးတယ်

၃. Long-lived listener တွေမှာ bind() သုံးသင့်တယ်

  • Event listener တွေ

  • Timer callback တွေ

  • Global event handler တွေ

၄. { once: true } option ကို မမေ့ပါနဲ့

  • Automatic cleanup ဖြစ်စေတယ်

  • Memory leak ကို ပိုကာကွယ်ပေးတယ်

Performance Tips

  • Large object တွေရှိတဲ့ scope မှာ arrow function မသုံးပါနဲ့

  • Long-lived event တွေမှာ bind() သုံးပါ

  • Cleanup logic ကို သေချာ ရေးပါ

  • Memory profiler နဲ့ test လုပ်ပါ

Reference

ECMAScript Specification:

  • §15.3.3: Arrow Function Definitions

  • §20.2.3.2: Function.prototype.bind

  • §10.4.1: Bound Function Exotic Objects

  • §6.2.4: Reference Record

အကြံပြုချက်: Memory leak က web application တွေမှာ အဓိက performance problem တစ်ခု ဖြစ်တယ်။ bind() method ကို မှန်မှန်သုံးရင် ဒီ problem ကို ထိရောက်စွာ fix လုပ်နိုင်ပါတယ်။

Last updated