2009-10-06 25 views
8

Rất nhiều những gì tôi đã học về VB tôi đã học được từ việc sử dụng phân tích mã tĩnh (đặc biệt là phân tích dự án của Aivosto). Và một trong những điều nó kiểm tra là liệu bạn có xóa tất cả các đối tượng và mảng hay không. Tôi đã từng làm điều này một cách mù quáng vì PA nói vậy. Nhưng bây giờ tôi biết một chút về cách VB phát hành tài nguyên, có vẻ như với tôi rằng những điều này sẽ xảy ra tự động. Đây có phải là một tính năng kế thừa từ trước VB6, hoặc là có một lý do tại sao bạn nên đặt rõ ràng các đối tượng trở lại không có gì và sử dụng Erase trên mảng?Là đối tượng thanh toán bù trừ/mảng deallocation thực sự cần thiết trong VB6/VBA (Pros/Cons?)

Trả lời

4

Vấn đề, như tôi hiểu, phải làm với thực tế là VB6 (và tiền nhiệm của nó) có nguồn gốc của nó trong COM, và hệ thống thu gom rác tham chiếu của nó.

Hãy tưởng tượng, ví dụ, bạn khai báo một tham chiếu đến một đối tượng từ thư viện của bên thứ ba. Đối tượng đó có một số tham chiếu COM được sử dụng để giữ cho nó tồn tại và để xác định khi nào nó sẽ bị hủy. Nó không bị phá hủy khi bạn đặt nó thành Không có gì, nhưng khi số lượng tham chiếu của đối tượng đạt đến 0.

Hiện tại, không phải tất cả thành phần COM đều được viết bằng Visual Basic. Một số được viết bằng C hoặc C++. Xử lý ngoại lệ có cấu trúc không tồn tại trên tất cả các ngôn ngữ. Vì vậy, nếu một lỗi xảy ra, số lượng tham chiếu trên đối tượng đã không được đảm bảo để được giảm đúng, và các đối tượng COM đã được biết đến để treo xung quanh lâu hơn họ đã dự định. Đây không phải là vấn đề với Visual Basic. Đó là một vấn đề COM. (Và đó, bạn có thể lưu ý, là lý do tại sao. NET không sử dụng tính tham chiếu.)

Đó là lý do tại sao các nhà phát triển Visual Basic trở nên ám ảnh về việc phát hành các tham chiếu đối tượng trước khi thoát khỏi các thường trình. Bạn chỉ đơn giản là không biết những gì một thành phần bạn đang phân bổ được tạo ra dưới mui xe. Nhưng khi bạn phát hành tham chiếu đến nó, bạn ít nhất sẽ giải phóng số tham chiếu của bạn với nó. Nó đã trở thành gần như một câu thần chú tôn giáo. Khai báo, sử dụng, phát hành. Đó là cách COM làm việc.

Chắc chắn, Visual Basic có thể tốt hơn hoặc nhanh hơn tại các biến dereferencing tôi đã khai báo trên ngăn xếp. Nhưng chết tiệt, tôi muốn nó là OBVIOUS rằng những đối tượng đã được phát hành. Một chút bảo đảm sẽ diễn ra rất lâu khi bạn đang cố gắng theo dõi rò rỉ bộ nhớ.

0

Tôi luôn làm điều đó để thực hành tốt, bạn không bao giờ biết ngoại lệ có thể làm gì nếu bạn rơi vào một và các đối tượng của bạn không bị phân phối. Bạn nên relase chúng trong báo cáo cuối cùng và đảm bảo họ không sử dụng bất kỳ bộ nhớ nếu không bạn có thể chạy vào một rò rỉ bộ nhớ.

Tôi gặp sự cố bên trong hệ thống theo dõi thời gian đơn giản, nơi máy chủ tiếp tục gặp sự cố ngẫu nhiên, phải mất vài tuần để xác định đó là rò rỉ bộ nhớ của đối tượng được tự hủy. Mã của tôi đã được ném vào một ngoại lệ và không bao giờ được dọn dẹp sau khi chính nó gây ra máy chủ (trang web thực sự không phải toàn bộ máy chủ) để đi xuống.

+0

Thú vị, có thể hỏi loại đối tượng đó là gì? Phạm vi của nó là gì? Có phải nó là một ngoại lệ bị trói buộc được ném ra, hay ứng dụng chỉ bị hỏng? Khi một ngoại lệ tiêu chuẩn được ném, thủ tục được thoát. Ngay cả khi ngoại lệ, tất cả các tham chiếu cục bộ vẫn tự động bị hủy. Vì vậy, nếu không có tài liệu tham khảo cho các đối tượng bên ngoài các thủ tục, những gì đã gây ra các đối tượng để ở "sống"? – Oorang

+2

Không có khối Thử/Bắt/Cuối cùng hoặc Ngoại lệ trong VB6/VBA. – HardCode

+0

Không có khối Thử/Bắt/Cuối cùng, nhưng có những ngoại lệ có thể tra cứu được. Có một cái nhìn tại Err.Raise. – Oorang

-2

Có, đặt tất cả các đối tượng thành Không có gì và dọn sạch hết mức có thể. VB6 nổi tiếng vì có rò rỉ bộ nhớ khi không dọn dẹp công cụ của bạn. Thu gom rác thải là phụ cận trong VB6/VBA.

+0

Hi HardCode, tôi thường nghe ý kiến ​​này thể hiện. Những gì tôi đang cố gắng cho dù là một ví dụ cụ thể/tái sản xuất? – Oorang

+0

Không có gì sai với cơ chế thu gom rác của VB6. Đó là các thành phần khác không phát hành đúng tài liệu tham khảo hoặc yêu cầu ngữ nghĩa teardown rất cụ thể phá vỡ nó. Nó không phải là lỗi của VB6 rằng có những thành phần kém được viết không tuân thủ các quy tắc. –

+4

Đôi khi bạn cần phải phá bỏ một cách rõ ràng những thứ như tham chiếu đối tượng hình tròn. Nói chung phạm vi-thoát sẽ phát hành refences địa phương và deallocate mảng nhưng trong một phạm vi tồn tại lâu dài như dữ liệu mô-đun toàn cầu bạn có thể cũng được khuyên để làm sạch chiến lược sớm vào dịp chỉ để tài nguyên bộ nhớ miễn phí. Vấn đề là không có quy tắc chung. Bạn cần phải nhận thức được những gì bạn đang làm và khi có giá trị trong deallocation sớm. – Bob77

13

Matt Curland, tác giả của Advanced Visual Basic 6, người biết nhiều hơn về Visual Basic hơn hầu hết chúng ta sẽ nghĩ rằng đó là nỗ lực lãng phí. Xem xét báo giá này (tr110) về DAO, thư viện truy cập dữ liệu COM chủ yếu nhắm mục tiêu Cơ sở dữ liệu Access:

một ví dụ khác về mã rớt kém. DAO có các phương thức đóng phải là được gọi đúng thứ tự và các đối tượng cũng phải được phát hành theo thứ tự đúng (Recordset trước Cơ sở dữ liệu). hành vi mô hình đối tượng nghèo đơn lẻ có dẫn đến quan niệm sai lầm rằng VB rò rỉ bộ nhớ trừ khi bạn đặt rõ ràng tất cả biến cục bộ thành không có gì ở cuối của hàm. Đây là khái niệm hoàn toàn sai trong một mô hình đối tượng được thiết kế tốt. VB có thể xóa các biến nhanh hơn ở cuối dòng Dòng con hơn bạn có thể từ mã và nó sẽ kiểm tra các biến ngay cả khi bạn giải thích rõ ràng các tham chiếu của bạn. Bất kỳ nỗ lực nào bạn thực hiện đều bị trùng lặp.

+0

Xin chào ODW, Điều này song song với suy nghĩ của tôi. DAO là đối tượng duy nhất mà tôi biết chắc chắn phải được phát hành chính xác (bên ngoài Win32). Bạn có biết về bất kỳ "trường hợp đặc biệt" nào khác không? – Oorang

2

Bạn đã đọc số Aivosto web page này (từ người sáng tạo của Project Analyzer) chưa?

Nếu bạn đang sử dụng các biến tĩnh, điều quan trọng là để đòi lại bộ nhớ họ chiếm đóng khi bạn không cần biến nữa. Với bộ nhớ biến động không phải là quá nhiều của một vấn đề , bởi vì chúng bị phá hủy khi thủ tục kết thúc.

Nói cách khác, bạn không cần phải lo lắng về việc xóa các biến cục bộ, không tĩnh, cục bộ.

+0

+1 Để nhận thấy điều đó :) Mặc dù đó là một ngày khá hiếm khi tôi sử dụng statics. Tôi thường chỉ sử dụng các biến cấp mô-đun riêng nếu tôi cần một cái gì đó được ghi nhớ. – Oorang

Các vấn đề liên quan