0Pricing
Lua Academy · บทเรียน

การหลีกเลี่ยงหน่วยความจำรั่ว

เรียนรู้รูปแบบที่ทำให้เกิดหน่วยความจำรั่วใน Lua และกลยุทธ์ป้องกัน

การหลีกเลี่ยงหน่วยความจำรั่ว เป็นบทเรียน Lua Academy ฟรีบน CoddyKit นี่คือบทเรียนที่ 4 จากทั้งหมด 4 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7 บทเรียนนี้เป็นส่วนหนึ่งของเส้นทางการเรียน Lua Academy และความก้าวหน้าของคุณจะซิงค์ข้ามเว็บและแอป CoddyKit คอร์ส Lua Academy มีบทเรียนทั้งหมด 4 บทเรียน

หน่วยความจำรั่วใน Lua คืออะไร

หน่วยความจำรั่วเกิดขึ้นเมื่อวัตถุสะสมอยู่ในหน่วยความจำ เพราะการอ้างอิงทำให้ GC ไม่สามารถเก็บคืนวัตถุเหล่านั้นได้ แม้ว่าโปรแกรมจะไม่ต้องการใช้อีกต่อไปแล้ว

การรั่วไหลที่พบบ่อย: การสะสมในตัวแปรส่วนกลาง

การเก็บวัตถุไว้ในตารางส่วนกลางโดยไม่ลบออกเป็นสาเหตุคลาสสิกของหน่วยความจำรั่ว ตารางส่วนกลางเป็นรากของ GC อยู่เสมอ

local cache = {}  -- global-like upvalue
function storeResult(key, val)
  cache[key] = val  -- never evicted!
end

การแก้ไข: แคชที่มีขนาดจำกัด

จำกัดขนาดแคชและนำรายการเก่าออกโดยใช้กลยุทธ์ LRU หรือจำกัดขนาดอย่างง่าย

local MAX = 100
local function boundedStore(cache, key, val)
  if #cache >= MAX then
    table.remove(cache, 1)  -- evict oldest
  end
  cache[key] = val
end

การรั่วไหลที่พบบ่อย: ตัวรับฟังเหตุการณ์

การลงทะเบียนคลอเชอร์เป็นตัวรับฟังเหตุการณ์โดยไม่ยกเลิกการลงทะเบียน จะทำให้ทั้งคลอเชอร์และค่าที่คลอเชอร์ยึดไว้ยังคงมีชีวิตอยู่

local listeners = {}
function on(event, fn)
  listeners[event] = listeners[event] or {}
  listeners[event][#listeners[event]+1] = fn
end
-- Always provide off() to deregister!

การแก้ไข: ตารางตัวรับฟังแบบอ่อน

เก็บตัวรับฟังไว้ในตารางค่าแบบอ่อน เพื่อให้ตัวรับฟังถูกลบออกโดยอัตโนมัติเมื่อวัตถุผู้สมัครรับเหตุการณ์ถูกเก็บคืน

local listeners = setmetatable({}, {__mode = "v"})

การรั่วไหลที่พบบ่อย: คลอเชอร์ที่ยึดตารางขนาดใหญ่

คลอเชอร์ที่ยึดตารางขนาดใหญ่จะทำให้ตารางนั้นยังคงมีชีวิตอยู่ตราบเท่าที่คลอเชอร์ยังมีชีวิตอยู่ แม้ว่าจะต้องการใช้เพียงส่วนเล็ก ๆ ของตารางก็ตาม

local bigData = {-- 100MB of data --}
local fn = function()
  return bigData[1]  -- bigData stays alive!
end

การแก้ไข: แยกเฉพาะค่าที่ต้องใช้

แยกเฉพาะค่าที่ต้องใช้ก่อนสร้างคลอเชอร์ เพื่อให้สามารถเก็บคืนตารางขนาดใหญ่ได้

local needed = bigData[1]
bigData = nil  -- allow collection
local fn = function() return needed end

หน่วยความจำรั่วจากโครูทีน

โครูทีนที่ถูกพักการทำงานยังคงมีชีวิตอยู่และเก็บตัวแปรภายในทั้งหมดไว้ โครูทีนที่จบการทำงานแล้ว (สถานะ "dead") สามารถถูกเก็บคืนได้ อย่าทำโครูทีนที่ถูกพักการทำงานสูญหายจากการติดตาม

การสะสมของสตริง

การต่อสตริงในลูปด้วย .. จะสร้างสตริงชั่วคราวจำนวนมาก ใช้ table.concat เพื่อสร้างสตริงขนาดใหญ่อย่างมีประสิทธิภาพ

local parts = {}
for i = 1, 1000 do parts[i] = tostring(i) end
local result = table.concat(parts, ",")

การแก้จุดบกพร่องของหน่วยความจำรั่ว

ใช้ collectgarbage("count") ก่อนและหลังการทำงานเพื่อวัดการเพิ่มขึ้นของหน่วยความจำ บันทึกการเพิ่มขึ้นที่น่าสงสัยเพื่อจำกัดขอบเขตแหล่งที่มาของการรั่วไหล

local before = collectgarbage("count")
-- ... run operation ...
collectgarbage()
local after = collectgarbage("count")
print(("Delta: %.1f KB"):format(after - before))

เครื่องมือวิเคราะห์ประสิทธิภาพ

เครื่องมืออย่าง luamemprof และตัวนับการจัดสรรหน่วยความจำแบบกำหนดเองด้วย debug.sethook สามารถติดตามได้ว่าเส้นทางการทำงานใดจัดสรรหน่วยความจำมากที่สุด

คำถามเกี่ยวกับหน่วยความจำรั่ว

รูปแบบใดมีแนวโน้มทำให้เกิดหน่วยความจำรั่วมากที่สุด

ทบทวน: การหลีกเลี่ยงหน่วยความจำรั่ว

หน่วยความจำรั่วใน Lua เกิดจากแคชที่ขยายไม่จำกัด ตัวรับฟังที่ไม่ได้ยกเลิกการลงทะเบียน คลอเชอร์ที่ยึดตารางขนาดใหญ่ และโครูทีนที่ถูกพักการทำงานแต่ถูกลืม ใช้ตารางแบบอ่อน แคชที่มีขนาดจำกัด และ collectgarbage("count") เพื่อตรวจจับและป้องกันการรั่วไหล

คำถามที่พบบ่อย

บทเรียน “การหลีกเลี่ยงหน่วยความจำรั่ว” ฟรีหรือไม่

ใช่ — ข้อความเต็มของ “การหลีกเลี่ยงหน่วยความจำรั่ว” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส Lua Academy ให้อัปเกรดเป็น CoddyKit PRO คอร์ส Lua Academy มีบทเรียนทั้งหมด 4 บทเรียน

คุณจะเรียนรู้อะไรในบทเรียน “การหลีกเลี่ยงหน่วยความจำรั่ว”

เรียนรู้รูปแบบที่ทำให้เกิดหน่วยความจำรั่วใน Lua และกลยุทธ์ป้องกัน คุณปฏิบัติ Lua Academy ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 24/7 ตอบคำถามของคุณขณะที่คุณไปผ่านบทเรียน

คุณต้องมีประสบการณ์ก่อนที่จะเริ่มเรียน Lua Academy หรือไม่

ไม่จำเป็นต้องมีประสบการณ์มาก่อน Lua Academy บน CoddyKit ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 4 จากทั้งหมด 4 บทเรียน

บทเรียน “การหลีกเลี่ยงหน่วยความจำรั่ว” ใช้เวลานานแค่ไหน

บทเรียน CoddyKit ส่วนใหญ่ใช้เวลาประมาณ 5–10 นาที แต่ละบทเรียนจึงสั้นและเป็นแบบโต้ตอบ คุณสามารถก้าวหน้าอย่างต่อเนื่องและกลับมาเรียนต่อจากตรงที่เพิ่งหยุดบนเว็บและแอปได้เลย

ฉันเขียนและรันโค้ดในบทเรียน Lua Academy นี้ได้ไหม

ได้ บทเรียน Lua Academy ทุกบทมีตัวแก้ไขโค้ดในตัว คุณจึงเขียนและรันโค้ดจริงได้เลยในเบราว์เซอร์ และได้รับข้อเสนอแนะจาก AI ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ

บทเรียนทั้งหมดในหลักสูตรนี้

  1. พื้นฐานตัวเก็บขยะของ Lua
  2. คีย์อ่อนและค่าอ่อน
  3. ตัวทำลายด้วย __gc
  4. การหลีกเลี่ยงหน่วยความจำรั่ว
← กลับไปที่ Lua Academy