Nhờ giúp viết Code cách check các biến chưa được giải phóng khỏi bộ nhớ (1 người xem)

Liên hệ QC

Người dùng đang xem chủ đề này

hung2412

Thành viên tích cực
Tham gia
5/8/08
Bài viết
929
Được thích
240
Giới tính
Nam
Xin chào các bạn GPE!
Tôi có 1 vấn đề sau: Sau khi chạy thủ tục Sub thì có Code nào check các biến chưa được giải phóng khỏi bộ nhớ không?
Mã:
Sub Check_cac_bien_chua_duoc_giai_phong_khoi_bo_nho()
Dim i as Long
Dim t as Long
Dim k as String

... Code ...

End Sub
Mong các bạn giúp cho.
 

File đính kèm

VBA sử dụng reference counting để quản lý biến và bộ nhớ, giản dị hơn garbage collection nhiều.
Mọi thứ đằng sau Excel được Microsoft viết bằng C++
Muốn biết về ba cái này thì ở GPE có một chuyên viên nổi tiếng về tài viết lại các routines của Microsoft để tăng tốc. Hỏi người này hy vọng sẽ có câu trả lời.

Tên và thành tích nhơn vật này, làng C++ ai cũng biết. Nếu không biết đến thì đừng có mở miệng đòi dạy 200 đô một tiết.
 
Upvote 0
Tên và thành tích nhơn vật này, làng C++ ai cũng biết. Nếu không biết đến thì đừng có mở miệng đòi dạy 200 đô một tiết.
Nếu tôi không lầm, tức theo danh sách đăng ký, thì 2 "nhơn" vật này cùng dự sinh nhật GPE Sài Gòn mà. Hay là đã không có màn giao lưu, ngồi vào bàn cũng không ai tự giới thiệu?
 
Upvote 0
Nếu tôi không lầm, tức theo danh sách đăng ký, thì 2 "nhơn" vật này cùng dự sinh nhật GPE Sài Gòn mà. Hay là đã không có màn giao lưu, ngồi vào bàn cũng không ai tự giới thiệu?
Tại trước đó hỏng có ai hỏi "nhờ viết code cho hai đỉnh cao C++ nhận ra nhau khi đối diện trong bữa tiệc"
 
Upvote 0
Cảm ơn các bạn. Có ai nói cụ thể hơn được không ạ?
 
Upvote 0
Cảm thấy quá buồn câu hỏi hết sức là đơn giản nhưng đến giờ vẫn chưa có câu trả lời thỏa mã.
 
Upvote 0
...
Mã:
Sub Phong_Thi_Nghiem(Bien As Variant)
    If IsEmpty(Bien) Then
       MsgBox "[Bien] này vẫn còn trong trắng !"
    Else
       MsgBox "[Bien] này đã bị sử dụng !"
    End If
End Sub

Sub Tét_Bien_1()
    Dim Bien As Variant
    '---------> Côt
    Phong_Thi_Nghiem Bien
End Sub

Sub Tét_Bien_2()
    Dim Bien As Variant
    '---------> Côt
    Bien = "Anh ơi tối nay mình gặp nhau nhé !"
    Phong_Thi_Nghiem Bien
End Sub
 
Upvote 0
IsEmpty có đồng nghĩa với "chưa giải phóng" không?
Cháu cũng đang định hỏi bạn ấy "giải phóng" là như thế nào ? Mục đích rõ ràng cụ thể ?
Nhưng hỏi nhiều lại sợ làm phiền đến bạn ấy do đó mà cháu viết thí dụ để bạn test xem thế nào rồi phản hồi lại để biết tình hình.
 
Upvote 0
Cháu cũng đang định hỏi bạn ấy "giải phóng" là như thế nào ? Mục đích rõ ràng cụ thể ?
Nhưng hỏi nhiều lại sợ làm phiền đến bạn ấy do đó mà cháu viết thí dụ để bạn test xem thế nào rồi phản hồi lại để biết tình hình.
"Giải phóng" có nghĩa là:
Mã:
Dim i as long => i=Empty
Dim k as String => k=Empty
Dim t as Variant => t=Empty
Dim Wb As Workbook => Set Wb=Nothing
Dim Arr()  => Erase Arr
Dim rng as Range => Set rng=Nothing
Dim Dic As Object => Set Dic=Nothing
 
Upvote 0
@ptm0412 đấy như vậy cháu cũng hiểu sơ ý muốn của bạn ấy, 3 cái biến này:
Dim i as Long
Dim t as Long
Dim k as String

Như vậy cháu sử dụng IsEmpty là đúng ý của bạn ấy rồi đớiii.
 
Upvote 0
Ẩn tàng bên trong câu hỏi là "tất cả biến" và "tất cả kiểu biến". @Ba mười ba gói dép chuẩn bị bỏ chạy là vừa

Cháu biết sức của cháu nên cháu chỉ trả lời theo yêu cầu của #1 chú ạ, hết "biến" lại mọc thêm "hình" thì cháu phải chạy thôi..
@chủ thớt tham khảo thêm:

1600959094377.png
 
Upvote 0
Chỉ những người ăn chay trường mới trả lời được vấn đề này thôi.

Chúc mọi người ngon giấc mùa thu!
 
Upvote 0
@ptm0412 đấy như vậy cháu cũng hiểu sơ ý muốn của bạn ấy, 3 cái biến này:
Dim i as Long
Dim t as Long
Dim k as String

Như vậy cháu sử dụng IsEmpty là đúng ý của bạn ấy rồi đớiii.
Bạn chưa trả lời về mấy cái Objects. Mấy cái này mới là khùng.

Set rg = Range(gì gì đó)
Set rg = Nothing chỉ có nghĩa là không chỉ rg vào cái Range gì gì đó nữa. Nhưng cái Range gì gì đó nó thuộc về Worksheet và Workbook, đâu đã "giải phóng" khỏi bộ nhớ?
Loại biến này chỉ giải phóng vì sợ để đó bị ảnh hưởng cái Range mà nó chỉ vào thôi (lỡ tay đặt Value = cái gì đó). Chứ về bộ nhớ thì nó chỉ chiếm vài bytes.

Loại biến chỉ vào cái đối tượng (Object) được dựng ra mới quan trọng với bộ nhớ.
Set Dic = Nothing có nghĩa là bứt cái Dic ra khỏi cái đối tượng (object) mà nó đang chỉ vào. Đâu có bảo đảm "giải phóng" cái đối tượng ấy đâu?
Một thằng nợ nhiều nhà băng. Một vài nhà băng xoá nợ không có nghĩa là thằng ấy sạch nợ.
VBA dùng reference count để đếm số này. Chỉ khi nào số count này là 0 thì VBA mới tin là đối tượng đã được "tự do". Và lúc ấy nó mới tính chuyện lấy lại bộ nhớ.
Điển hình:
Set Dic = CreateObject("CaiGiDo") ' dựng đói tượng theo lớp CaiGiDo, ref count ở đây là 1
... code nhét đầy cỡ vài GB vào Dic
Set Dic2 = Dic ' chỉ Dic2 vào đối tượng kia, ref count ở đây là 2
Set Dic = Nothing ' bứt Dic ra, ref count ở đây là 1, vì thằng Dic2 còn sờ sờ kia
... code gì thì cứ code
' cái đối tượng kia vẫn sừng sững chiếm vài GB vì VBA đâu thể dẹp nó. Mỗi lần VBA hỏi thăm thì nó trả lời "ref count của tao vẫn đang > 0"
Set Dic2 = Nothing ' bứt Dic2 ra, bây giờ thì ref count là 0 (nếu không còn thằng nào nữa)
... code gì đó đòi hỏi bộ nhớ
' VBA sẽ lại hỏi cái đối tượng kia, và lần này thì nó trả lời "tao đi chầu Phật đây, mày cứ việc lây lại cái đống bọ nhớ kia
' bấy giờ cái chỗ bộ nhớ kia mới thực sự được tính là phơ-ri.

Ví dụ trên thì đếm dễ rồi. Vì các ref's đều trực tiếp. Mọi việc sẽ rối như tơ vò nếu có việc chỉ-qua-chỉ-lại (cross references)
Điển hình là đối tượng ADO thỉnh thoảng bị VBA đếm nhầm ref count, Excel đơ luôn.

Bảo tôi code cái này thì tôi chịu. Hơi đâu bỏ cả tuần lễ (có thể đến cả tháng, tôi học chậm lắm) đi tìm tài liệu rồi viết mấy cái sub's để làm chuyện từ thiện. Cả tháng ấy thà đi viết code dạo, lấy tiền đem vào bệnh viện giúp người nghèo mua thuốc có lẽ còn nhiều "công đức" hơn.

Nhưng ở trên tôi đã mách cho một chuyên viên C++. Tôi tin là người này có khả năng làm nhanh và tốt hơn tôi. Những điều y khoe về trình độ C++ đều thật cả. Và tôi có nói rõ với thớt rồi, không biết y là ai thì chỉ là tay mơ trong làng C++. Đừng có mở miệng khoác lác cái vụ C++ 200 đô một tiết, nghe nực cười lắm.
 
Upvote 0
Dạo tôi đi "cua" bà xã tôi thì tôi ở SG và bả đang ở Mỹ tho.
Mỗi ngày tôi siêng năng đu xe đò từ bến xe miền Tây về Mỹ tho. Nhưng xe Mỹ tho đỗ ở bến (vừa qua Trung lương, vào thành là bến rồi). Cho nên tôi đi xe Chợ gạo. Vừa qua cầu Nguyễn Trãi thì tôi nhảy xuống (xe không dám dừng, vì công an thấy sẽ phạt) và đi bộ về nhà cô ấy.
Chiều lại tôi đón xe Chợ gạo cũng khoảng chỗ ấy mà về SG.
Có những buổi "bịn rịn ướt át" (như nhạc bô lê rô vậy) quá nên chỉ còn chuyến xe chót, chật người.
Tôi kể chuyện để bà con biết chuyện đi xe nhảy, đu, ngồi tùm lum chỗ chả lạ gì với tôi cả. Hai lần rùng rợn nhất là:
Lần 1. phải đeo cái thang leo sau xe cho tới gần Tân An. Đeo một bên thang, bên kia là anh lơ xe. Đến gần Tân An mới có người xuống bớt và tôi được vào trong xe.
Lần 2. phải ngồi lên cái nắp máy kế tài xế, ngay sát cái cần số. Tôi không sợ anh tài "nắm lộn cần số" nhưng phải nói là cái nắp máy nó nóng cháy đít. Về tới bến Bình chánh là đít tôi bốc khói ngùn ngụt.
 
Upvote 0
Vấn đề là biết trước và không leo lên, dù trong hay ngoài. Tuy nói vậy nhưng khó, đang đói bài thì bất chấp
Trường hợp của tôi là chuyến xe cuối cùng của ngày bác ơi. Không nhảy lên không được.
Trễ xe ở lại cũng không đến nỗi chết (chỉ mất công trình báo công an phường). Nhưng mà làm vậy mất mặt với bên cô ấy lắm. Hồi xưa đâu phải như bây giờ tụi trẻ chúng muốn ngủ lang ở đâu cũng được.

Vả lại, nếu cái gì nó cũng có cái giá của nó thì những cái mình trả giá đắt nó cũng có hiệu dụng sau này. Mấy chục năm rồi, mỗi lần giận tôi (quên ngày cưới) cô ấy nghĩ lại cái nghề "nhảy xe" của tôi là nguôi ngoai ngay. Mấy chục năm tôi có mua cho cô ấy món quà sinh nhật hay va -lăn-tin gì đâu (tôi bài Tây mờ, không thích theo lệ bọn Tây)
 
Upvote 0
Trường hợp của tôi là chuyến xe cuối cùng của ngày bác ơi. Không nhảy lên không được.
Ý tôi nói bạn mà tôi trích dẫn chứ không phải anh, và việc lên xe buýt đến điểm X không phải là yêu cầu bắt buộc như anh.
Cũng có khi muốn tự thử thách việc khó nhưng phải tự lượng sức trước tiên.
 
Upvote 0
Ý tôi nói bạn mà tôi trích dẫn chứ không phải anh, và việc lên xe buýt đến điểm X không phải là yêu cầu bắt buộc như anh.
Cũng có khi muốn tự thử thách việc khó nhưng phải tự lượng sức trước tiên.
Tôi hiểu là bác nói bạn kia. Mình hết chuyện rồi nên mượn bàn phím để bàn phiếm chơi vậy thôi. :p
 
Upvote 0
Dạo tôi đi "cua" bà xã tôi thì tôi ở SG và bả đang ở Mỹ tho.
Mỗi ngày tôi siêng năng đu xe đò từ bến xe miền Tây về Mỹ tho. Nhưng xe Mỹ tho đỗ ở bến (vừa qua Trung lương, vào thành là bến rồi). Cho nên tôi đi xe Chợ gạo. Vừa qua cầu Nguyễn Trãi thì tôi nhảy xuống (xe không dám dừng, vì công an thấy sẽ phạt) và đi bộ về nhà cô ấy.
Chiều lại tôi đón xe Chợ gạo cũng khoảng chỗ ấy mà về SG.
Có những buổi "bịn rịn ướt át" (như nhạc bô lê rô vậy) quá nên chỉ còn chuyến xe chót, chật người.
Tôi kể chuyện để bà con biết chuyện đi xe nhảy, đu, ngồi tùm lum chỗ chả lạ gì với tôi cả. Hai lần rùng rợn nhất là:
Lần 1. phải đeo cái thang leo sau xe cho tới gần Tân An. Đeo một bên thang, bên kia là anh lơ xe. Đến gần Tân An mới có người xuống bớt và tôi được vào trong xe.
Lần 2. phải ngồi lên cái nắp máy kế tài xế, ngay sát cái cần số. Tôi không sợ anh tài "nắm lộn cần số" nhưng phải nói là cái nắp máy nó nóng cháy đít. Về tới bến Bình chánh là đít tôi bốc khói ngùn ngụt.
Lần 2 ko cẩn thận lại hỏng cả nồi khoai Thầy ạ :p
 
Upvote 0
Câu hỏi này thú vị phết mà giờ mới biết. Nhưng theo những gì mà tôi đã biết qua thì các biến được giải phóng khỏi bộ nhớ hoàn toàn không giống cách hiểu của đa số mọi người ở đây.
Trong các ngôn ngữ bậc thấp, khi bạn khai báo một biến trong chương trình thì nghĩa là chương trình đó đã trong bộ nhớ một khoảng vừa đủ để chứa dữ liệu tương lai của cái biến đấy. Trong ngôn ngữ C hay C++, nếu chương trình khai báo một biến X kiểu int đồng nghĩa với việc chương trình đó xí ngay một chỗ rộng 4 byte (hay 2 byte) gì đó trên RAM. Và một điều khá buồn cười là dù chưa làm ăn gì với cái biến X đó thì rất có thể nó đã chứa sẵn một giá trị ngẫu nhiên rồi chứ hổng phải là giá trị 0 mặc định như trong nhiều ngôn ngữ khác. Giá trị ngẫu nhiên này chính là những gì còn sót lại trong ô nhớ RAM trước đó mà cái biến X vô tình được cấp lại đúng các ô nhớ này. Bởi thế với C/C++, khởi tạo các giá trị cụ thể cho biến nào đó là điều giúp chương trình tránh được những lỗi logic đau đầu.

Với các ngôn ngữ bậc cao hơn chẳng hạn như VB, người ta làm sẵn cái khâu khởi tạo này. Chẳng hạn trong VB, tôi khai báo biến X kiểu đồng nghĩa với 2 việc:
[1] cấp phát bộ nhớ​
[2] đưa dữ liệu vùng nhớ đó về giá trị mặc định là 0.​
Với các kiểu dữ liệu phức tạp hơn nhưng struct, object, thì chắc hẳn sẽ có nhiều bước phức tạp và trình biên dịch tạo ra một cơ chế đặc thù quản lý các biến có kiểu này.

Bởi thế ở cái thời dung lượng RAM máy tính chỉ tính bằng MB (tương đương 0.1-0.4% dung lượng bộ nhớ tiêu chuẩn bây giờ), VB6 bắt buộc bạn bỏ đi những biến không bao giờ dùng đến khi biên dịch nhằm tối ưu việc sử dụng bộ nhớ (vì cứ khai báo là nó chiếm bộ nhớ rồi). Việc giải phóng bộ nhớ nếu có chỉ xẩy ra khi ta bước ra khỏi vùng có khai báo biến đó nhưng thực chất cũng chả có cái "giải phóng bộ nhớ" đúng nghĩa bao giờ. Các dẫy ô nhớ có độ dài khác nhau đã được cấp phát trước đó dù không còn dùng đến vẫn khó được thu hồi lại và dẫn đến hiện tượng phân mảnh RAM.

Và cách giải quyết cho tình huống đau đầu này chính là tăng dung lượng RAM. Từ dung lượng tính bằng đơn vị KB, sau nhiêu năm đã nhẩy lên MB và nay là GB, mỗi lần thay đổi đơn vị tính, dung lượng RAM lại tăng thêm hơn 1000 lần. Các máy hoạt động càng lâu, đóng mở nhiều app, nhiều thread tương đương với việc khai báo nhiều biến.. thì càng phải dự phòng một bộ nhớ càng lớn. Điều này không chỉ xẩy ra với Windows mà còn là sự đau đầu của Android. Trong Android có một app tối ưu sử dụng RAM nhưng chỉ có thể kích hoạt bằng tay con người chứ Android cũng hổng dám tự động giải quyết. Tuy nhiên hệ điều hành của Apple giải quyết tương đối thành công vấn đề này cho nên RAM trong các thiết bị của Apple thường chỉ bằng 1/2 thậm chí là 1/4 dung lượng RAM các thiết bị có hiệu năng tương đương chạy hệ điều hành khác.

Chốt lại, "Giải phóng bộ nhớ" chỉ là khái niệm tồn tại trong đầu chúng ta chứ chả có trong máy tính trừ khi restart. Bạn đã khai báo một biến bất kỳ thì nó nghiễm nhiên chiếm đủ số bộ nhớ tiêu chuẩn dành cho nó dù có dùng đến hay không. Bác nào có thể giải quyết vấn nạn "chiếm dụng bộ nhớ vô ích" triệt để thì Microsoft, Google... thậm chí Apple sẽ đưa hẳn chuyên cơ đón bác cùng dòng họ qua Mỹ. --=0
 
Lần chỉnh sửa cuối:
Upvote 0
Hèn chi em thấy Apple chạy mượt hơn Androi, kỳ này để dành tiền mua cái ĐT Apple quá:p
 
Upvote 0

Bài viết mới nhất

Back
Top Bottom