การจับข้อยกเว้น OutOfMemoryException ใน C#
System.OutOfMemoryException เกิดขึ้นเมื่อ CLR ไม่สามารถจัดสรรหน่วยความจำเพียงพอสำหรับอ็อบเจกต์ใหม่ได้ สืบมาจาก System.SystemException
สถานการณ์ตัวอย่าง
การใช้ StringBuilder กำหนด Capacity เท่ากับความยาวเริ่มต้น แล้วพยายาม Insert เพิ่มเติม
ตัวอย่างโค้ดที่ทำให้เกิด Exception
using System;
using System.Text;
namespace Demo
{
class Program
{
static void Main(string[] args)
{
try
{
string studentName = "Tom";
string studentSubject = "Maths";
// Capacity = Length = 3, MaxCapacity = 3 (ไม่สามารถขยายได้)
StringBuilder sb = new StringBuilder(studentName.Length, studentName.Length);
sb.Append(studentName); // "Tom"
// พยายาม Insert เพิ่ม -> OutOfMemoryException
sb.Insert(studentSubject, studentName.Length - 1, 1);
}
catch (OutOfMemoryException e)
{
Console.WriteLine("Error: Out of memory");
Console.WriteLine(e.Message);
}
}
}
}
ผลลัพธ์
Error: Out of memory
Out of memory
สาเหตุทั่วไปของ OutOfMemoryException
- สร้างอ็อบเจกต์ขนาดใหญ่เกินไป (Large Object Heap > 85KB)
- Memory Leak (Event handlers ไม่ Unsubscribe, Static References)
- StringBuilder กำหนด MaxCapacity ต่ำเกินไป
- ประมวลผลข้อมูลขนาดใหญ่ใน 32-bit Process (จำกัด 2GB/4GB)
แนวทางแก้ไขและป้องกัน
- ใช้
64-bit Process(Prefer 32-bit = false ใน Project Properties) - หลีกเลี่ยงการเก็บข้อมูลขนาดใหญ่ใน Memory นานๆ (Streaming, Chunking)
- ใช้
StringBuilderโดยไม่กำหนด MaxCapacity หรือกำหนดให้พอเพียง - Implement
IDisposableและ เรียกDispose()ให้ถูกต้อง - ใช้
GC.TryStartNoGCRegionสำหรับ Critical Sections (Advanced)
หมายเหตุ
ใน .NET Core / .NET 5+ GC ปรับปรุงแล้ว จัดการ Large Objects ดีกว่า แต่ยังควรเขียนโค้ดให้ Memory Efficient