Vậy thế nào là một đối tượng có thể truy cập: Một đối tượng được gọi là có thể truy cập nếu nó tồn tại ít nhất một biến tham chiếu tới nó trong chương trình, hoặc trực tiếp hoặc thông qu
Trang 1Viện Công Nghệ Thông Tin & Truyền Thông
-o0o -BÁO CÁO TIỂU LUẬN NGUYÊN LÝ CÁC NGÔN NGỮ LẬP TRÌNH
Đề bài: 05 Tìm hiểu các kỹ thuật dọn rác nhớ (Gabage collection) Giảng viên: TS Nguyễn Hữu Đức
Nhóm sinh viên thực hiện:
STT Mã học viên Họ và tên
1 CB120113 Phạm Tất Thành (Trưởng nhóm)
2 CB120116 Nguyễn Xuân Thịnh
3 CB120097 Trần Văn Nậm
Lớp: 12BCNTT2
Hà nội 2012
Trang 2MỤC LỤC
A Phần 1 – Giới thiệu 3
1 Gabage collection là gì? 3
2 Những nguyên tắc cơ bản 3
3 Ưu nhược điểm của bộ dọn rác (GC) 3
4 Một số kỹ thuật GC phổ biến 4
4.1 Tracing Gabage Collection 4
4.2 GC in Runtime Systems 6
B Phần 2 - Bộ đếm tham chiếu 6
2 Đếm tham chiếu 6
2.1 Phương pháp ban đầu 6
C Phần 3 – Đánh dấu và giải phóng rác 11
3 Đánh dấu và giải phóng rác 11
3.1 Các giải pháp truyền thống 11
3.2 Đánh dấu các đối tượng rác 11
3.3 Giải phóng bộ nhớ 12
Trang 3TÌM HIỂU CÁC KỸ THUẬT DỌN RÁC NHỚ
A Phần 1 – Giới thiệu
1 Gabage collection là gì?
Trong khoa học máy tính, GC là dạng quản lý bộ nhớ tự động GC giải phóng bộ nhớ bị chiếm dụng bởi một biết hay đối tượng không còn được sử dụng trong chương trình
GC được John McCarthy đưa ra vào năm 1959 để giải quyết những vấn
đề của ngôn ngữ Lisp
GC thường được mô tả đối lập với việc quản lý bộ nhớ chủ động (manual), yêu cầu lập trình viên phải chỉ định những đối tượng bị hủy để trả lại tài nguyên bộ nhớ cho hệ thống
Tài nguyên của hệ thống còn có kết nối mạng, cơ sở dữ liệu, cửa sổ tương tác của người dùng, tệp và thường không xử lý bằng GC
2 Những nguyên tắc cơ bản
Tìm những đối tượng dữ liệu trong chương trình không được truy cập trong tương lai Lấy lại tài nguyên được sử dụng bởi những đối tượng đó
Rất nhiều ngôn ngữ sử dụng GC (ví dụ: Java, C# và hầu hết các ngôn ngữ kịch bản) GC luôn luôn kết hợp chặt chẽ với cấp phát bộ nhớ
GC thực hiện theo chu trình được định sắn, hoặc khi tài nguyên sắp bị thiếu khi thực hiện
3 Ưu nhược điểm của bộ dọn rác (GC)
Ưu điểm:
GC giải phóng lập trình viên từ việc phải chủ động hủy, giải phóng bộ nhớ Kết quả là một số lỗi đã được loại bỏ hoặc giảm thiểu đáng kể:
Trang 4• Lỗi con trỏ, khi một phần bộ nhớ được giải phóng trong khi đó những con trỏ khác vẫn trỏ tới nó
• Lỗi xảy ra khi chương trình cố gắng giải phóng vùng bộ nhớ đã được giải phóng và thậm chí có thể đã được cấp phát một lần nữa
• Một số loại rò rỉ bộ nhớ, chương trình không giải phóng bộ nhớ bị chiếm đóng dẫn đến cạn kiệt tài nguyên
• Một số lỗi khác được giải quyết bằng GC có thể có những tác động an ninh
Nhược điểm:
• GC tiêu thụ tài nguyên máy tính trong việc đưa ra quyết định giải phóng
bộ nhớ, thậm chí lập trình viên đã biết về những thông tin này Đây chính là hình phạt cho việc không xác định, quản lý thời gian sống của của đối tượng trong chương trình, nó có thể dẫn đến giẩm hiệu suất của chương trình Việc tương tác với những bộ nhớ phân cấp có thể làm cho chi phí này không thể chấp nhận được vì rất khó để dự đoán hay phát hiện, thử nghiệm thường xuyên
• Thời điểm để GC hoặt động có thể không đoán trước được
• Không xác định được GC tương thích với RAII (bộ khởi tạo tài nguyên)
4 Một số kỹ thuật GC phổ biến
4.1 Tracing Gabage Collection
Là loại GC phổ biến nhất
Cơ chế hoạt động: Đầu tiên nó xác định những đối tượng có thể truy cập
hoặc có khả năng truy cập, sau đó loại bỏ tất cả những đối tượng còn lại
Vậy thế nào là một đối tượng có thể truy cập:
Một đối tượng được gọi là có thể truy cập nếu nó tồn tại ít nhất một biến tham chiếu tới nó trong chương trình, hoặc trực tiếp hoặc thông qua tham chiếu từ đối tượng có thể truy cập khác Chính xác hơn, đối tượng có thể truy cập trong hai cách:
Trang 5• Giả sử một tập các đối tượng có thể truy cập, được gọi là roots Nó bao gồm tất cả các đối tượng được tham chiếu từ bất kỳ đâu (các biến địa phương và các tham số trong các hàm hiện tại đang được gọi) và toàn bộ những biến toàn cục
• Bất kỳ tham chiếu từ đối tượng có thể truy cập, bản thân nó là có thể truy cập Có thể truy cập là bao đóng bắc cầu
Strong and Weak References
• GC chỉ có thể hủy những đối tượng không có tham chiếu đến chúng Tuy nhiên một vài chương trình yêu cầu Weak References, cái mà nên được
sử dụng càng lâu càng tốt đối tượng tồn tại, nhưng cũng không nên kéo dài thời gian sống của nó Một đối tượng sẽ bị hủy nếu nó không có tham Strong References, thậm chí nó có tồn tại một số Weak References trỏ đến nó
• Weak References không chỉ đơn thuần là con trỏ trỏ tới đối tượng cái mà
GC không quan tâm đến Thuật ngữ này thường được dành riêng cho những đối tượng tham chiếu đặc biệt, cái mà là an toàn ngay cả khi đối tượng đã bị biến mất bởi vì chúng mất hiệu lực đến một giá trị an toàn Trong thực tế, Weak References được chia thành các loại nhỏ Ví dụ Java Virtual machine cung cấp 3 dạng Weak References:
+ Soft References
+ Phantom References
+ Regular weak References
Microsoft.NET cung cấp 2 dạng Weak References:
+ Namely long weak references
+ Soft weak references
• Cấu trúc dữ liệu có thể cũng được nghĩ ra để có những tính năng theo dõi Weak Ví dụ, các bảng băm Weak là hữu ích, giống như các bảng băm thông thường, một bảng băm weak duy trì mối liên hệ giữa các cặp đối tượng, nơi mà mỗi cặp được hiểu là một chìa khóa và giá trị Nhưng bảng băm không thực sự duy trì một Strong references trên những đối tượng Một động thái đặc biệt được diễn ra khi khóa hay giá trị hay cả hai trở thành rác
Trang 64.2 GC in Runtime Systems
Trong các hệ thống thời gian thực, cái phải đáp ứng cho những sự kiện trong thời gian ràng buộc, Bộ GC phải không được dừng thực hiện một vài phút, một vài giây hoặc thậm chí là mili giây tùy thuộc vào nhiệm vụ của ứng dụng
Bộ thu phân phối công việc của mình và cho phép ứng dụng đang chạy Nó được thực hiện xen kẽ với chương trình thực hiện Loại GC này được gọi là gia tăng bộ nhớ
Như đã biết, bộ đếm tham chiếu có thể dễ dàng sửa đổi để được gia tăng Tuy nhiên hiệu quả của nó là không đủ trong nhiều trường hợp Do đó bộ sao chép
và tạo đã được thực hiện gia tăng
Sự khác nhau giữa các chương trình đang chạy song song với bộ thu gom phải thay đổi biểu đồ của các đối tượng truy cập trong khi bộ thu gom đang làm việc trên một phần của đồ thị khác Cái mà được xem như là điều chỉnh xử lý đồng thời cấu trúc dữ liệu
The Tricolor marking scheme
Vấn đề của đánh dấu song song có thể được mô tả với sơ đồ đánh dấu 3 màu
ảo Bộ theo dõi có thể được mô tả như biểu đồ tịnh tiến của đối tượng sống và màu của chúng Khởi tạo ban đầu, tất cả các đối tượng có màu trắng, và khi kết thúc quá trình sống, đối tượng nên được đặt là màu đen
Trong lớp xử lý đánh dấu, màu được thực hiện trực tiếp bởi đánh dấu những bit Bit của những đối tượng được truy cập là là tập hợp
B Phần 2 - Bộ đếm tham chiếu
2 Đếm tham chiếu
2.1 Phương pháp ban đầu
Giống như mô tả trong [Coll60] và [Weiz63], một trường thêm, gọi là đếm tham chiếu, đã được giới thiệu tới từng đối tượng, trường này cho biết số lần đối tượng được tham chiếu, trường này phải được cập nhật mỗi khi một con
Trang 7trỏ đến đối tượng được tạo ra hoặc bị hủy bỏ, khi bộ đếm bằng không thì đối tượng không hoạt động và có thể dọn Nếu nó là một cấu trúc thì toàn bộ những trường của nó được kiểm tra và đếm tham chiếu
(Hình 1 Phân loại các kỹ thuật dọn rác nhớ)
Trang 8Việc giảm giá trị của đối tượng tham chiếu.Thông thường, khi một tham chiếu duy nhất cấu trúc lớn được giải phóng, tất cả các tính toán tham chiếu của các đối tượng trong cấu trúc đó trở thành số không và tất cả các đối tượng được thu hồi
Theo lý thuyết, đếm tham chiếu phải đủ lớn để nắm giữ số tham chiếu có thể bằng nhiều nhất là số lượng các ô nhớ Do đó, việc bộ đếm phải là lớn như một con trỏ
Ưu điểm chính của kỹ thuật này là thời gian dọn rác nhớ được phân phối và không chỉ dừng lại việc thực hiện các chương trình cho một số lượng đáng kể thời gian, đó cũng là một hạn chế cơ bản về hệ thống thời gian thực và tương tác Các ô không hoạt động có thể được lưu trữ trong một ngăn xếp ngầm thực hiện như là một danh sách liên kết Bản thân các ô trống có thể lưu trữ các con trỏ Phân bố lại không thích hợp vì chuyển quá sự cải thiện của toàn
bộ cấu trúc dữ liệu Giữ một danh sách rỗng nhưng đối tượng nhưng chưa xử
lý có thể phân phối thu hồi đệ quy
Những lợi thế lớn khác của phương pháp này là tính địa phương.Trong khi các thuật toán khác quét toàn bộ bộ nhớ, thì bộ đếm tham chiếu làm việc với các đối tượng tại địa phương.Trong một hệ thống sử dụng bộ nhớ ảo hoặc môi trường phân trang hoặc thậm chí chạy trên máy tính gần đây bằng cách sử dụng những bộ nhớ cache, việc sử dụng tính địa phương của bộ nhớ là rất quan trọng Số lượng lớn các lỗi trang được gọi là khi dữ liệu cần thiết không phải là trong bộ nhớ nhanh nhất thì có thể làm chậm đáng kể hệ thống (Tính năng này cũng có thể là một bất lợi vì các đối tượng sống không được phân tán trong toàn bộ bộ nhớ.)
Tuy nhiên, phương pháp này có một số nhược điểm Đầu tiên, thêm không gian cần thiết cho nhiều những máy tính chiếm số lượng đáng kể của bộ nhớ Thứ hai, việc cập nhật thường xuyên của các máy tính làm cho một chi phí về thời gian thực hiện, chi phí là tỷ lệ thuận với số lượng công việc được thực
Trang 9hiện bởi các chương trình đang chạy Thứ ba, phương pháp này là không thể đòi lại các cấu trúc vòng Cuối cùng, nó có thể được nhận xét rằng đếm tham chiếu tập trung vào các đối tượng trở thành rác nhớ trong khi các phương pháp khác đi qua các đồ thị của các đối tượng sống Các số liệu thống kê cho thấy số lượng các đối tượng sống luôn luôn là ít hơn đáng kể so với số lượng các đối tượng rác nhớ
Kích thước của các bộ đếm có thể là nhỏ hơn so với một con trỏ Sau khi số tham chiếu có thể lưu trữ tối đa đạt được, bộ đếm không được tăng lên hoặc giảm đi.Trong trường hợp đó, các đối tượng tham chiếu nhiều lần không thể được cải thiện khi chúng trở thành rác thải Tuy nhiên, các số liệu thống kê cho thấy hầu hết các đối tượng được tham chiếu chỉ một lần Thực tế này có thể được đưa vào xem xét trong bộ đếm tham chiếu, phương pháp đếm kích thức từng bit một được thực hiện trong [Chi87] (xem [Ina90]) Nó chỉ có thể lấy lại rác nhớ của các đối tượng tham chiếu duy nhất Deutsch và Bobrow sử dụng bảng băm cho các hệ thống LISP để xử lý các đối tượng tham chiếu duy nhất có hiệu quả, xem Bob75, Deu76, [Coh81]
Các chi phí thời gian bao gồm hai loại chi phí Một chi phí là thường xuyên cập nhật bộ đếm bất cứ khi nào một con trỏ trỏ đến đối tượng được tạo ra hoặc bị hủy bỏ Đối số đi qua tại thủ tục kích hoạt tạo ra biến ngắn ngủi, được đặt trên các ngăn xếp của hệ thống Trong những trường hợp này, số lượng bộ đếm tham chiếu được tăng lên và giảm đi trong một khoảng thời gian rất ngắn, chi phí này có thể được loại bỏ bằng cách xử lý đặc biệt của các biến địa phương
Một chi phí khác không thể được loại bỏ Khi một đối tượng được lấy lại, thông thường, điều này liên quan đến việc liên kết các đối tượng được giải phóng vào một hoặc nhiều "danh sách trống”
Bộ đếm tham chiếu là không thể phát hiện "rác mạch vòng" một số đối tượng tham chiếu với nhau, nhưng chúng không thể truy cập bởi các chương
Trang 10trình.Ví dụ, biểu đồ cấu trúc dữ liệu hoặc cây với các nút có chứa chu kỳ chứa con trỏ quay lui đến chu kỳ chứa nút cha Xem hình 2, chu kỳ phức tạp đôi khi được hình thành bởi việc sử dụng các cấu trúc dữ liệu lai kết hợp một số cấu trúc dữ liệu đơn giản nếu như một chương trình tạo ra nhiều vòng Mặc
dù, có một số giải pháp để phục hồi các cấu trúc vòng (xem ví dụ [Les92]), chúng thực sự không hiệu quả
(Hình 2: Bài toán với các cấu trúc vòng)
Ngay cả nếu kích thước của các bộ đếm là nhỏ thì các đối tượng tham chiếu nhiều lần vẫn còn trong bộ nhớ trong thời gian thực hiện toàn bộ chương trình
Vì vậy, bộ đếm tham chiếu dọn rác thường bao gồm một loại dọn khác được thực hiện khi bộ nhớ đầy và phương pháp đầu tiên không đủ không gian rảnh Trong những năm gần đây, chi phí của đếm tham chiếu và sự thất bại của nó với các cấu trúc tròn làm cho nó không hấp dẫn với hầu hết người thực hiện.Các phương pháp đánh dấu thu hồi thường hiệu quả và đáng tin cậy hơn
Trang 11C Phần 3 – Đánh dấu và giải phóng rác
3 Đánh dấu và giải phóng rác
3.1 Các giải pháp truyền thống
Thu dọn rác được thực hiện trong 2 pha Pha đầu, đánh dấu các đối tượng có thể truy cập; Pha thứ hai, thực hiện quét toàn bộ bộ nhớ và các đốitượng đã đánh dấu được tập hợp lại trong một vùng nhớ liền nhau
3.2 Đánh dấu các đối tượng rác
Có một số các đối tượng được truy cập tức thời trong chương trình, như các biến toàn cục, biết địa phương và các thanh ghi hệ thống Chúng được gọi là
“tập gốc” và chứa những tham chiếu đến các đối tượng trong bộ nhớ Nếu một cấu trúc dữ liệu có thể truy cập đến các đối tượng khác tham chiếu qua những trường của cấu trúc dữ liệu cho phép truy cập Thủ tục đánh dấu được định nghĩa đệ quy như sau:
Proceduremark(p); { p is a reference, i.e a pointer to a data object }
begin
integeri;
ifnot_marked(p) then
begin
mark_data(p);
ifstructure(p) then
begin
fori := 1 tonumber_of_fields(p) domark( field(p,i) );
end
end
endmark;
Giải thích:
- Hàm number_of_fields(p) tính số trường dữ liệu của cấu trúc dữ liệu mà p (p
là một tham chiếu tới đối tượng dữ liệu) tham chiếu tới Các trường này được kiểm tra đệ quy Hàm field(p,i) thực hiện cho một tham chiếu tới trường dữ liệu thứ i của cấu trúc dữ liệu tham chiếu bởi p
- Thủ tục này có thể được cài đặt không đệ quy bằng cách sử dụng một ngăn xếp Các ô của ngăn xếp trỏ tới các tham chiếu cần kiểm tra Khi một cấu trúc
Trang 12dữ liệu được đánh dấu, các trường dữ liệu của nó tham chiếu tới các cấu trúc chưa đánh dấu sẽ được đẩy vào ngăn xếp Thủ tục đánh dấu sử dụng tham chiếu đến đỉnh của ngăn xếp –chứa “tập gốc” bắt đầu thực hiện đánh dấu Thủ tục thực hiện cho đến khi ngăn xếp rỗng Đây là phương thức có tốc độ nhanh nhưng về lý thuyết thì kích thước ngăn xếp phải tương ứng với kích thước của
bộ nhớ Nếu bộ nhớ chưa N cấu trúc và tất cả chúng đếu được truy cập từ một phần tử thuộc “tập gốc”, thì kích thước của ngăn xếp tăng lên gần bằng N
- Để trách vấn đề ngăn xếp cần kích thước lớn, Knuth sử dụng một ngăn xếp có kích thước h cố định Knuth lưu các tham chiếu theo kiểu vòng – tính chỉ số của phần tử trong ngăn xếp bằng phép mod h Khi chỉ số của tham chiếu tính
ra lớn hơn h, thì lại bắt đầu lại từ chỉ số 0 và ghi đè lên các thông tin trước đó Bởi vậy, ngăn xếp chỉ gọi lại h mục dữ liệu truy cập gần nhất và không xử lý tới các mục còn lại Tất nhiên, ngăn xếp có thể rỗng trước khi toàn bộ việc thực hiện đánh dấu hoàn thành Khi điều này xảy ra, bộ nhớ được quết từ địa chỉ thấp nhất, tìm kiếm các đối tượng được đánh dấu mà nội dung của các đối tượng này tham chiếu tới các đối tượng chưa đánh dấu Nếu như một đối tượng được tìm thấy, việc đánh dấu tiếp tục như trước khi tìm thấy và lại thực hiện cho đến khi ngăn xếp rỗng hoặc khi hoàn thành tác vụ Không phải toàn
bộ bộ nhớ được quét qua nếu thủ tục ghi được ít nhất các tham chiếu bị mất
- Tác vụ có thể được hoàn thành mà không sử dụng ngăn xếp Chú ý, lời gọi thủ tục đệ quy bao hàm việc sử dụng ngăn xếp không tường minh và bộ nhớ
có thể bị đầy trong quá trình thực hiện đánh dấu
3.3 Giải phóng bộ nhớ
- Quét các đối tượng dữ liệu rác
Phương thức đơn giản nhất cho việc giải phóng các đối tượng dữ liệu là kết hợp các ô không đánh dấu vào một hay nhiều danh sách đối tượng rác
+ Việc này có thể thực hiện được bằng cách giữ một danh sách cho mỗi đối tượng có kích thước phổ biến được sử dụng trong chương trình Các danh sách này được gọi là các danh sách thuần nhất (H-list) Ngoài ra, danh sách đối tượng rác khác, M-list, chứ các ô của các đối tượng có kích thước khác