Module 1 — Tổng kết & cheat sheet
Recap mô hình bộ nhớ chương trình: địa chỉ, con trỏ, stack frame, heap, fragmentation, ba vùng nhớ. Cheat sheet một trang, glossary, pitfall và self-assessment.
TL;DR: Module 1 bóc tách cách một chương trình đang chạy bố trí bộ nhớ: mọi biến sống tại một địa chỉ, con trỏ/tham chiếu là biến lưu địa chỉ, stack chứa frame lời gọi (nhanh, tự dọn), heap chứa object động (linh hoạt, tốn kém, dễ fragment), và static chứa dữ liệu sống suốt đời chương trình. Đây là một trang để bookmark.
Đã đi qua những gì
Bạn bắt đầu từ khái niệm gốc — bộ nhớ là dãy ô đánh số, con trỏ là biến lưu số ô đó — rồi dùng nó để hiểu hai vùng nhớ đối lập. Stack cho biến cục bộ: mỗi lời gọi hàm push một frame, biến sống và chết theo frame, cực nhanh nhưng nhỏ và ngắn hạn. Heap cho dữ liệu động: cấp phát kích thước tuỳ ý lúc chạy, sống lâu hơn hàm, nhưng cần allocator và dễ bị fragmentation. Cuối cùng bạn đặt cả ba vùng (thêm static) cạnh nhau và rút ra quy tắc chọn vùng đúng cho từng dữ liệu — nền tảng để Module 2 nói về cache và Module 3 nói về bộ nhớ ảo.
mindmap
root(("Mo hinh<br/>bo nho"))
Dia chi
O nho danh so theo byte
Con tro = bien luu dia chi
Tham chieu Java/Python
Stack
Frame moi loi goi ham
Tu don theo LIFO
Stack overflow khi de quy sau
Heap
Cap phat dong qua allocator
Fragmentation
Song lau hon ham
Chon vung
Nho ngan han to stack
Lon song lau to heap
Hang dung chung to static🗺️ Cheat sheet
| Khái niệm | Cốt lõi | Pitfall thường gặp |
|---|---|---|
| Địa chỉ | Số thứ tự của ô nhớ (từ 0) | Nhầm địa chỉ với giá trị |
| Con trỏ / tham chiếu | Biến lưu một địa chỉ | Gán biến object = copy địa chỉ, không copy nội dung (aliasing) |
Dereference (*p, obj.x) | Đi tới địa chỉ để đọc/ghi | Dereference null → NullPointerException |
| Pass-by-value (Java) | Copy giá trị; với object là copy reference | Tưởng gán lại tham số đổi biến gốc |
| Stack frame | Tham số + biến cục bộ + return addr | Trả về con trỏ tới biến cục bộ (C) |
| Stack overflow | Frame chồng vượt giới hạn stack | Đệ quy sâu phụ thuộc input |
| Heap allocator | Duyệt free list, cắt khối | Cấp phát object tạm trong vòng lặp nóng |
| Fragmentation | Trống rải rác, không khối lớn liền | "Còn bộ nhớ" mà vẫn OutOfMemory |
| GC compaction | Dời object sống, nén heap | (C không làm được — fragment tích luỹ) |
| Static / global | Cấp một lần, sống cả chương trình | static mutable → race condition |
📖 Glossary module
| Thuật ngữ | Định nghĩa 1 câu |
|---|---|
| Address (địa chỉ) | Số thứ tự duy nhất của một ô nhớ trong RAM, bắt đầu từ 0 |
| Pointer (con trỏ) | Biến mà giá trị là một địa chỉ, "trỏ tới" ô nhớ khác |
| Reference (tham chiếu) | Tên Java/Python cho con trỏ ẩn — biến object lưu địa chỉ object trên heap |
| Dereference | Đi tới địa chỉ một con trỏ lưu để đọc hoặc ghi giá trị ở đó |
| Aliasing | Hai biến cùng trỏ tới một object → sửa qua biến này thấy ở biến kia |
| Stack | Vùng nhớ LIFO chứa frame lời gọi hàm, tự dọn theo frame |
| Stack frame | Khối nhớ một lời gọi hàm: tham số, biến cục bộ, địa chỉ trả về |
| Stack pointer | Thanh ghi theo dõi đỉnh stack; push/pop là dịch thanh ghi này |
| Stack overflow | Lỗi khi tổng frame vượt giới hạn stack (thường do đệ quy sâu) |
| Heap | Vùng nhớ lớn cho cấp phát động, vòng đời tuỳ ý |
| Allocator | Bộ quản lý heap: tìm khối trống, cắt, đánh dấu, gộp khi free |
| Free list | Cấu trúc allocator dùng để theo dõi các khối nhớ trống |
| Fragmentation | Bộ nhớ trống vỡ vụn (external) hoặc dư trong khối (internal) |
| Compaction | GC dời object còn sống về sát nhau để dồn vùng trống |
| Static / BSS / Data | Vùng chứa biến toàn cục và hằng, sống suốt đời chương trình |
| Escape analysis | Phân tích compiler: object không thoát khỏi hàm có thể đặt trên stack |
⚠️ Pitfall tổng hợp
1. Gán biến object tưởng là copy:
List<String> backup = original; // SAI: copy dia chi
List<String> backup = new ArrayList<>(original); // DUNG: copy noi dung
2. Gán lại tham số tưởng đổi biến gốc:
void f(String s) { s = s.toUpperCase(); } // chi doi tham chieu cuc bo
void f(List<String> l) { l.add("x"); } // sua noi dung -> thay o noi goi
3. Đệ quy sâu phụ thuộc input → tràn stack:
void traverse(Node n) { ...; traverse(n.next); } // SAI voi list 100k phan tu
// DUNG: vong lap + ArrayDeque tren heap
4. Cấp phát object tạm trong vòng lặp nóng:
for (...) { StringBuilder sb = new StringBuilder(); ... } // SAI
StringBuilder sb = new StringBuilder();
for (...) { sb.setLength(0); ... } // DUNG: tai dung
5. Static mutable dùng chung giữa luồng:
static int count = 0; void inc() { count++; } // SAI: race condition
private final AtomicInteger count = new AtomicInteger(); // an toan hon
✅ Self-assessment
Bạn đã đạt module này nếu trả lời được:
- Explain được địa chỉ bộ nhớ và con trỏ là gì, vì sao mọi biến đều có địa chỉ — kể cả trong Java/Python.
- Nếu chưa: đọc lại bài 01 mục 2–3.
- Trace được cách stack frame được tạo và huỷ qua mỗi lời gọi hàm, và giải thích stack overflow.
- Nếu chưa: đọc lại bài 02 mục 2–3.
- Explain được heap, cấp phát động và vì sao fragmentation làm chậm hoặc cạn bộ nhớ.
- Nếu chưa: đọc lại bài 03 mục 2–3.
- Choose được vùng nhớ đúng (stack, heap, static) cho từng loại dữ liệu và giải thích trade-off.
- Nếu chưa: đọc lại bài 04 mục 4.
🚀 What's next
Module 2 — Cache & memory hierarchy — trả lời câu hỏi tiếp theo: bạn đã biết dữ liệu sống ở đâu (stack/heap/static), nhưng truy cập nó nhanh chậm thế nào? Hoá ra RAM chậm hơn CPU hàng trăm lần, và cache là lớp đệm cứu vãn điều đó. Bạn sẽ học vì sao bố cục dữ liệu trong bộ nhớ (chứ không chỉ thuật toán) quyết định tốc độ, và cách viết code "thân thiện cache" nhanh gấp nhiều lần mà không đổi độ phức tạp big-O.
Bài tiếp theo: Module 2 — Cache & memory hierarchy: tổng quan
📚 Tài liệu mở rộng
- Sách: Computer Systems: A Programmer's Perspective (Bryant & O'Hallaron) — chương 3 (machine-level representation) và 9 (virtual memory) là nền tảng vàng cho cả track.
- Sách: The Garbage Collection Handbook (Jones, Hosking, Moss) — sâu về allocator và GC, cho ai muốn đào tận gốc heap.
- Tài liệu: What Every Programmer Should Know About Memory (Ulrich Drepper) — kinh điển về bộ nhớ và cache, đọc dần qua Module 2.
- Thực hành: chạy một chương trình C nhỏ với
valgrind --tool=memcheckđể thấy rò bộ nhớ và truy cập sai vùng — cảm nhận trực tiếp điều module này mô tả.
Bài này có giúp bạn hiểu bản chất không?
Hỏi đáp về bài này
Chưa có câu hỏi
Có gì chưa rõ trong bài? Đặt câu hỏi đầu tiên — câu trả lời từ cộng đồng giúp bạn (và người sau).
Đặt câu hỏi đầu tiên