Stack vs. Heap: Tối ưu bộ nhớ trong Unity
C# Code
/*
* STACK (Ngăn xếp):
* - Rất nhanh, quản lý theo kiểu LIFO (Vào sau ra trước).
* - Mỗi luồng (thread) có một Stack riêng.
* - Lưu trữ "Value Types" (kiểu giá trị): int, float, bool, Vector3, Quaternion, và các 'struct' bạn tự định nghĩa.
* - Khi một hàm kết thúc, bộ nhớ trên Stack cho các biến của nó sẽ được giải phóng ngay lập tức.
* - Rất thân thiện với hiệu năng trong Unity.
*/
public struct Point { public int x, y; }
public void StackExample()
{
// 'a' và 'p1' là value types, được tạo trực tiếp trên Stack.
int a = 10;
Point p1 = new Point { x = 5, y = 5 };
// Khi gán, toàn bộ dữ liệu được sao chép.
int b = a;
Point p2 = p1;
b = 20; // Không ảnh hưởng đến 'a'.
p2.x = 30; // Không ảnh hưởng đến 'p1'.
}
/*
* HEAP (Đống):
* - Chậm hơn Stack, là vùng nhớ lớn và linh hoạt.
* - Lưu trữ "Reference Types" (kiểu tham chiếu): tất cả các 'class', string, array.
* - Khi tạo một đối tượng bằng 'new MyClass()', bộ nhớ được cấp phát trên Heap.
* - Biến của bạn trên Stack chỉ là một 'con trỏ' trỏ tới địa chỉ của đối tượng trên Heap.
* - Việc giải phóng bộ nhớ trên Heap được thực hiện bởi Garbage Collector (GC),
* đây là một tiến trình tốn kém có thể gây giật game (GC spike).
*/
public class Enemy { public int health; }
public void HeapExample()
{
// 'enemy1' là một tham chiếu trên Stack, trỏ đến một đối tượng Enemy trên Heap.
Enemy enemy1 = new Enemy { health = 100 };
// 'enemy2' là một tham chiếu khác trên Stack, trỏ đến CÙNG một đối tượng trên Heap.
Enemy enemy2 = enemy1;
enemy2.health = 50; // Thay đổi dữ liệu qua 'enemy2'.
// Vì cả hai cùng trỏ đến một đối tượng, 'enemy1.health' bây giờ cũng là 50.
}
/*
* KẾT LUẬN CHO UNITY DEV:
* - Ưu tiên dùng 'struct' cho các kiểu dữ liệu nhỏ, bất biến (immutable) để tránh tạo rác cho GC.
* - Chỉ dùng 'class' cho các đối tượng phức tạp, có trạng thái, và cần được chia sẻ qua tham chiếu.
* - Tránh việc 'new' các class trong hàm Update() bằng mọi giá!
*/Hiểu cách C# và Unity quản lý hai vùng nhớ Stack và Heap là chìa khóa để tối ưu hiệu năng. Việc sử dụng sai `class` (Heap) thay vì `struct` (Stack) cho các dữ liệu nhỏ có thể tạo ra hàng ngàn 'rác' (garbage), khiến Garbage Collector (GC) phải hoạt động và gây giật, lag game.