- vừa được xem lúc

Reset nhật ký tự học BE: Ngày 1 - Garbage Collector

0 0 2

Người đăng: Nguyễn Văn Biên

Theo Viblo Asia

Bình Phước, 6/4/2025

NÍ HẢO AE, 2 tuần trước là thật bận rộn vì mình phải chuyển trọ nên bỏ bê chuyện tự học. An cư lập nghiệp mà, phải ổn định chỗ ở thì đầu óc mới tập trung làm việc được. Ước gì có tiền mua hẳn 1 cái nhà dưới quê, về sống với bố mẹ, khỏi lo chuyển trọ nữa. Hehe. Thôi tính reset lại nhật ký he.



I - Garbage là gì?

Garbage là 1 vùng nhớ được khởi tạo nhưng không có con trỏ nào trỏ tới nó. Garbage là một vùng nhớ vô dụng, không được sử dụng. Dần dần nó sẽ dẫn đến hiện tượng memory leak.

Ví dụ với C++:

void someFunc() { int* ptr = new int(10); // Tạo một vùng nhớ mới, biến ptr sẽ trỏ vào vùng nhớ đó ptr = null; // mất tham chiếu từ ptr, tạo ra một garbage
}

Ví dụ với Dart:

void someFunc() { var obj = Object(); obj = null; // Giờ Object là 1 garbage vì obj đã mất tham chiếu đến nó.
}

Ví dụ với Go:

func someFunc() { ptr := new(int) *ptr = 10 ptr = null // mất tham chiếu từ ptr, tạo ra một garbage
}


II - Garbage collector (viết tắt: GC)

Quản lý pointer trong C++

Trong C++ không có khái niệm garbage chính thức cũng như built-in GC bởi vì ta phải tự tay quản lý bộ nhớ cho các pointer. Ví dụ:

void someFunc() { int* ptr = new int(10); // Tạo một vùng nhớ mới, biến ptr sẽ trỏ vào vùng nhớ đó delete ptr; // Giải phóng bộ nhớ ptr = null; // Đặt về nullptr để tránh dangling pointer
}

Đây là cách cơ bản nhất để quản lý bộ nhớ trong C++. Nội dung cũng khá đơn giản:

  • new thì phải có delete tương ứng.
  • delete xong thì phải đặt pointer về null để tránh trường hợp dangling pointer (vì bài viết này đang tập trung vào garbage nên mình xin skip phần dangling này nhé).

Các ngôn ngữ lập trình cấp cao hơn đều được tích hợp sẵn trình thu gom rác (built-in GC) và 99.99% công việc thường ngày của chúng ta sẽ chẳng cần quan tâm rằng GC là gì và nó sẽ hoạt động như thế nào. Tuy nhiên, nếu bạn có hứng thú với những thứ "under the hood", bạn nên tìm hiểu sâu hơn vì chúng rất thú vị đấy! Có khi còn pass được 1 câu hỏi phỏng vấn nữa chứ!


GC thường hoạt động như thế nào?

1. Nguyên lý cơ bản

GC hoạt động dựa trên 2 việc (nghe có vẻ là đơn giản) như sau:

  • Bước 1. Xác định garbage.
  • Bước 2. Thu hồi bộ nhớ (gom rác).

2. Các thuật toán GC phổ biến

Mark & Sweep:

  • Mark: Bắt đầu từ root (như các biến global, trong stack memory, thread...), duyệt đồ thị tới tất cả mọi nơi. Khi duyệt đồ thị, những object nào có đường đi tới thì được đánh dấu là còn sống.
  • Sweep: Duyệt qua toàn bộ heap memory, những object nào không được đánh giá còn sống, nghĩa là đó là garbage và cần phải bị loại bỏ.
  • Mark & Sweep rất cơ bản & dễ triển khai. Tuy nhiên, như mô tả phía trên, Mark & Sweep tuy đơn giản nhưng sẽ có thể gây chậm chạp. Nó phù hợp hơn với các hệ thống server.

Generational GC:

  • Dựa trên ý tưởng rằng, một số đối tượng sẽ có vòng đời ngắn (short-lived), một số đối tượng sẽ sống lâu hơn (long-lived).
  • Generational GC sẽ chia heap ra làm 2 vùng:
    • Young generation: Chứa các đối tượng mới được khởi tạo.
    • Old generation: Chứa các đối tượng đã nhiều lần sống sót qua nhiều làm gom rác.
  • GC sẽ chủ yếu quét & gom rác trong Young generation, vì nơi đây tạo ra nhiều rác nhất, chi phí xử lý cũng nhanh & ít ảnh hưởng hiệu năng. Flutter/Dart cũng sử dụng kiểu GC này.

Mark & Sweep là một cách thực thi rất cơ bản, trong khi ý tưởng của Generational GC là một trong những cách phổ biến nhất & tốt nhất hiện nay. Ngoài ra còn một số kiểu gom rác khác như Reference Counting nhưng mình không code ngôn ngữ nào xài nó cả và có vẻ nó cũng không tốt bằng Generational nên thôi skip nhá 😃.



III - GC trong Dart

Dart dùng kỹ thuật Generational GC. Bạn có thể đọc thêm về ý tưởng của Generational GC ở phía trên.

Trong quá trình hoạt động, Flutter luôn tạo ra rất nhiều widget + state nên sẽ gây ra rât nhiều garbage. Việc gom rác nhanh chóng và thường xuyên ở Young generation, kết hợp với một số kỹ thuật concurrencyschedule đúng cách sẽ giúp Flutter app luôn mượt mà và không bị drop FPS.

Đối với Young generation

Ở Young generation, Dart sử dụng kỹ thuật gọi là Semi-space GC. Heap sẽ được chia làm 2 nửa gọi là From-spaceTo-space. Bạn hãy quan sát hình bên dưới.

  • Khi một object mới xuất hiện, nó sẽ được khởi tạo trong vùng nhớ nằm ở From-space (2).
  • Khi nửa From-space đầy (3), GC sẽ kiểm tra xem những object nào còn sống (4), và di chuyển chúng tới nửa To-space (5).
  • Xoá sạch những garbage còn tồn tại trong From-space, và đổi vai trò của 2 nửa cho nhau (6). image.png Source ảnh: Flutter: Don’t Fear the Garbage Collector

Đối với Old generation

Sử dụng Mark-Sweep hoặc các biến thể như Mark-Compact.

IV - GC trong Go

// To be continue

Tham khảo

(1) Matt Sullivan. Flutter: Don’t Fear the Garbage Collector. URL: https://medium.com/flutter/flutter-dont-fear-the-garbage-collector-d69b3ff1ca30. Last accessed: 6/4/2025.

(2) Nima Farzin. Garbage Collection in Dart and Its Implications in Flutter. URL: https://nimafarzin-pr.medium.com/garbage-collection-in-dart-and-its-implications-in-flutter-aef9de51bfc4. Last accessed: 1/4/2025.

(3) AI Chatbots.

Bình luận

Bài viết tương tự

- vừa được xem lúc

Học Flutter từ cơ bản đến nâng cao. Phần 1: Làm quen cô nàng Flutter

Lời mở đầu. Gần đây, Flutter nổi lên và được Google PR như một xu thế của lập trình di động vậy.

0 0 293

- vừa được xem lúc

Học Flutter từ cơ bản đến nâng cao. Phần 3: Lột trần cô nàng Flutter, BuildContext là gì?

Lời mở đầu. Màn làm quen cô nàng FLutter ở Phần 1 đã gieo rắc vào đầu chúng ta quá nhiều điều bí ẩn về nàng Flutter.

1 1 353

- vừa được xem lúc

Flutter Animation: Creating medium’s clap animation in flutte Part II

Trong phần 1 mình đã giới thiệu với các bạn cơ bản về Animation trong Flutter. Score Widget Size Animation.

0 0 66

- vừa được xem lúc

Flutter - GetX - Using GetConnect to handle API request (Part 4)

Giới thiệu. Xin chào các bạn, lại là mình với series về GetX và Flutter.

0 0 363

- vừa được xem lúc

StatefulWidget và StatelessWidget trong Flutter

I. Mở đầu. Khi các bạn build một ứng dụng với Flutter thì Widgets là thứ không thể thiếu đúng không ạ. Và 2 loại Widget không thể thiếu đó là StatefullWidget và StatelessWidget.

0 0 149

- vừa được xem lúc

Tìm hiểu về Riverpod - Provider nhưng không hắn :v

Trong Flutter có rất nhiều các quản lý state: Provider, Bloc, GetX, Redux,... khó mà nói cái nào tốt hơn cái nào. Tuy nhiên nếu bạn đã làm quen với Provider thì không ngại để tìm hiểu thêm về Riverpod. Một bản nâng cấp của Provider. Nếu bạn để ý thì cái tên "Riverpod" là các chữ cái của "Provider" đ

0 0 69