nguyendang95
Thành viên thường trực




- Tham gia
- 25/5/22
- Bài viết
- 213
- Được thích
- 181
Chắc hẳn nhiều người khi tiếp xúc với VBA đã từng có thắc mắc như vậy, có người cho rằng nên Set Nothing trước khi kết thúc chương trình bởi vì VBA không tự động giải phóng bộ nhớ, nhưng cũng có người tin rằng chẳng cần phải mất công Set Nothing làm gì bởi vì VBA đủ thông minh để tự dọn dẹp bộ nhớ sau khi kết thúc chương trình. Trăm nghe không bằng một thấy, để tìm câu trả lời cho câu hỏi này, chúng ta hãy làm một bài thử nghiệm nhỏ. Bài viết này sử dụng mã viết bằng Visual C++, tạo một đối tượng COM tên là Employee đơn giản bằng ATL Project, đối tượng này có duy nhất một thuộc tính kiểu chuỗi tên là FullName như hình dưới đây:

Sau đây là hai mã VBA để chạy thử:
Mở Visual Studio, biên dịch dự án ra DLL rồi chạy trong chế độ gỡ lỗi (Debug), sau đó đặt điểm ngắt (breakpoint) ở phương thức FinalRelease của Employee.

Bắt đầu lần lượt chạy hai thủ trên. Khi chạy đến End Sub, trình gỡ lỗi của Visual Studio nhảy đến điểm ngắt trong phương thức FinalRelease, chứng tỏ VBA đã gọi phương thức Release để giải phóng đối tượng khỏi bộ nhớ (nên nhớ phương thức FinalRelease chỉ được gọi khi RefCount, hay đếm tham chiếu, của đối tượng bằng 0).

Cửa sổ Immediate ghi lại thông tin như sau, quá trình từ lúc khởi tạo đối tượng Employee (khởi tạo IClassFactory, IUnknown rồi mới cho ra IEmployee, giải phóng IClassFactory và IUnknown sau khi đã khởi tạo đối tượng xong), khởi tạo IDispatch từ IEmployee để thiết lập thuộc tính FullName của đối tượng Employee, xong việc rồi thì giải phóng IDispatch, cuối cùng là giải phóng đối tượng Employee (IEmployee) sau khi thủ tục kết thúc:

Kết luận: Không cần thiết phải Set đối_tượng Nothing trước khi kết thúc hàm/thủ tục.

Sau đây là hai mã VBA để chạy thử:
Mã:
Public obj As CollectionObjectsLib.Employee
Private Sub Test()
Set obj = New CollectionObjectsLib.Employee
obj.FullName = "AAA"
End Sub
Mã:
Private Sub Test2()
Dim obj As CollectionObjectsLib.Employee
Set obj = New CollectionObjectsLib.Employee
obj.FullName = "AAA"
End Sub
Mở Visual Studio, biên dịch dự án ra DLL rồi chạy trong chế độ gỡ lỗi (Debug), sau đó đặt điểm ngắt (breakpoint) ở phương thức FinalRelease của Employee.

Bắt đầu lần lượt chạy hai thủ trên. Khi chạy đến End Sub, trình gỡ lỗi của Visual Studio nhảy đến điểm ngắt trong phương thức FinalRelease, chứng tỏ VBA đã gọi phương thức Release để giải phóng đối tượng khỏi bộ nhớ (nên nhớ phương thức FinalRelease chỉ được gọi khi RefCount, hay đếm tham chiếu, của đối tượng bằng 0).

Cửa sổ Immediate ghi lại thông tin như sau, quá trình từ lúc khởi tạo đối tượng Employee (khởi tạo IClassFactory, IUnknown rồi mới cho ra IEmployee, giải phóng IClassFactory và IUnknown sau khi đã khởi tạo đối tượng xong), khởi tạo IDispatch từ IEmployee để thiết lập thuộc tính FullName của đối tượng Employee, xong việc rồi thì giải phóng IDispatch, cuối cùng là giải phóng đối tượng Employee (IEmployee) sau khi thủ tục kết thúc:

Kết luận: Không cần thiết phải Set đối_tượng Nothing trước khi kết thúc hàm/thủ tục.
