5.3.11 Rò rỉ bộ nhớ (Memory leaks)

Các constructors chúng ta đã thấy cho đến nay đã làm công việc của chúng thông qua việc khởi tạo các đối tượng, nhưng không có hành động nào của chúng được đảo ngược lại. Nói cách khác, sau khi đối tượng kết thúc cuộc đời của nó, không có gì để buộc chúng phải dọn dẹp.

Điều này khá hiếm trong lập trình thực. Nhiều đối tượng được cấp phát bộ nhớ mà chúng cần cho quá trình hoạt động của chúng. Bộ nhớ này sẽ được giải phóng khi đối tượng kết thúc hoạt động và cách tốt nhất để thực hiện việc này là tự động clean. Không giải phóng bộ nhớ sẽ gây ra một hiện tượng gọi là “rò rỉ bộ nhớ” (memory leaks), tức là bộ nhớ không còn được sử dụng nữa (nhưng vẫn còn cấp phát) ngày càng tăng lên, ảnh hưởng đến hiệu suất hệ thống.

Chúng tôi cũng có thể cố tình làm rò rỉ bổ nhớ như sau →

class Sample chỉ có một constructor, nó có trách nhiệm cấp phát bộ nhớ có kích thước được xác định bởi giá trị tham số của nó. Đối tượng của class này được tạo ra như là một biến địa phương bên trong hàm MakeALeak().

Chúng ta có thể tưởng tượng rằng việc tạo ra đối tượng bao gồm hai giai đoạn:

  1. Đối tượng chính nó được tạo ra và một phần của bộ nhớ được cấp phát ngầm cho đối tượng
  2. Constructor cấp phát một phần bộ nhớ khác

Biến object là một ví dụ của một “biến tự động” – automatic variable. Điều này có nghĩa là biến sẽ tự động kết thúc cuộc đời của nó khi việc thực hiện của hàm chứa khai báo của biến kết thúc.

Chúng ta có thể dự đoán rằng khi hàm MakeALeak() return nó sẽ gây ra hành động sau:

  • bộ nhớ được cấp phát cho chính đối tượng được giải phóng (điều này được thực hiện ngầm).

Thật không may, rõ ràng là bộ nhớ được cấp phát bởi constructor vẫn được đang cấp phát. Điều tồi tệ hơn là chúng ta đã mất con trỏ duy nhất lưu giữ địa chỉ của bộ nhớ đó (nó được lưu trữ biến value, nhưng đối tượng chứa value không còn tồn tại nữa).

Phần lớn bộ nhớ đã bị rò rỉ. Thật đáng tiếc.

Thiện tai, thiện tai.