การหลีกเลี่ยงหน่วยความจำรั่ว
เรียนรู้รูปแบบที่ทำให้เกิดหน่วยความจำรั่วใน 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 ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ
บทเรียนทั้งหมดในหลักสูตรนี้
- พื้นฐานตัวเก็บขยะของ Lua
- คีย์อ่อนและค่าอ่อน
- ตัวทำลายด้วย __gc
- การหลีกเลี่ยงหน่วยความจำรั่ว