2012-01-08 22 views

Trả lời

17

Mỗi JVM là khác nhau, nhưng HotSpot JVM không chủ yếu dựa vào tính tham khảo như một phương tiện để thu gom rác thải.Việc đếm tham chiếu có lợi thế là đơn giản để thực hiện, nhưng nó vốn dễ bị lỗi. Đặc biệt, nếu bạn có một chu trình tham chiếu (một tập các đối tượng mà tất cả tham chiếu đến nhau trong một chu kỳ), thì việc đếm tham chiếu sẽ không lấy lại chính xác các đối tượng đó bởi vì tất cả chúng đều có số tham chiếu không đồng bộ. Điều này buộc bạn phải sử dụng một bộ thu rác phụ trợ theo thời gian, có xu hướng chậm hơn (Mozilla Firefox có vấn đề chính xác này, và giải pháp của họ là thêm vào bộ thu gom rác với chi phí dễ đọc nhiều mã). Đây là lý do tại sao, ví dụ, các ngôn ngữ như C++ có xu hướng có sự kết hợp của shared_ptr s sử dụng tính tham chiếu và weak_ptr mà không sử dụng chu trình tham chiếu.

Ngoài ra, việc kết hợp số lượng tham chiếu với mỗi đối tượng làm cho chi phí chỉ định tham chiếu lớn hơn bình thường, do sổ sách kế toán bổ sung liên quan đến việc điều chỉnh số tham chiếu (chỉ trở nên tồi tệ hơn khi có đa luồng). Hơn nữa, việc sử dụng tính toán tham chiếu ngăn cản việc sử dụng các loại nhất định nhanh chóng của bộ cấp phát bộ nhớ, điều này có thể là một vấn đề. Nó cũng có xu hướng dẫn đến sự phân mảnh heap ở dạng ngây thơ của nó, vì các đối tượng nằm rải rác thông qua bộ nhớ hơn là đóng gói chặt chẽ, giảm thời gian phân bổ và gây ra địa phương nghèo.

JVM HotSpot sử dụng nhiều kỹ thuật khác nhau để thực hiện thu gom rác, nhưng bộ thu gom rác chính của nó được gọi là bộ thu dừng và sao chép. Bộ sưu tập này hoạt động bằng cách phân bổ các đối tượng liên tiếp trong bộ nhớ bên cạnh nhau và cho phép phân bổ các hướng đối tượng mới cực kỳ nhanh (một hoặc hai hướng dẫn lắp ráp). Khi không gian hết, tất cả các đối tượng mới được GC'ed đồng thời, mà thường giết chết hầu hết các đối tượng mới được xây dựng. Kết quả là, GC nhanh hơn nhiều so với triển khai tính toán tham chiếu thông thường, và kết thúc có địa phương tốt hơn và hiệu suất tốt hơn.

Để so sánh các kỹ thuật thu thập rác, cùng với tổng quan nhanh về cách GC trong HotSpot hoạt động, bạn có thể muốn xem these lecture slides từ khóa học trình biên dịch mà tôi đã dạy vào mùa hè năm ngoái. Bạn cũng có thể muốn xem the HotSpot garbage collection white paper sẽ đi vào chi tiết hơn về cách trình thu gom rác hoạt động, bao gồm các cách điều chỉnh bộ thu trên cơ sở từng ứng dụng.

Hy vọng điều này sẽ hữu ích!

+0

+1 Cũng đáng nói đến rằng các va chạm truy cập nguyên tử cho các chương trình đa luồng thậm chí còn đắt hơn. –

+1

Một cuộc thảo luận về điều này là không đầy đủ mà không đề cập đến tạm dừng GC. –

2

Vì nó không hoạt động đúng dựa trên việc tính tham chiếu.

Xem xét tham chiếu vòng tròn không còn có thể truy cập được từ "gốc" của ứng dụng.

Ví dụ:

APP có một tham chiếu đến SOME_SCREEN

SOME_SCREEN có một tham chiếu đến SOME_CHILD

SOME_CHILD có một tham chiếu đến SOME_SCREEN

bây giờ, APP giọt nó là tài liệu tham khảo để SOME_SCREEN.

Trong trường hợp này, SOME_SCREEN vẫn có tham chiếu đến SOME_CHILDSOME_CHILD vẫn có tham chiếu đến SOME_SCREEN - vì vậy, trong trường hợp này, ví dụ của bạn không hoạt động.

Bây giờ, những người khác (Apple với ARC, Microsoft với COM, nhiều người khác) có giải pháp cho điều này và làm việc tương tự như cách bạn mô tả nó. Với ARC, bạn phải chú thích các tham chiếu của mình với các từ khóa như strongweak để ARC biết cách xử lý các tham chiếu này (và tránh tham chiếu vòng tròn) ... (không đọc quá xa ví dụ cụ thể của tôi với ARC) bởi vì ARC xử lý những điều này trước trong suốt quá trình biên dịch và không yêu cầu thời gian chạy cụ thể cho mỗi lần, vì vậy nó có thể được thực hiện tương tự như cách bạn mô tả nó, nhưng nó không hoạt động được với một số tính năng Java. Tôi cũng tin rằng COM hoạt động tương tự như cách bạn mô tả ... nhưng một lần nữa, đó không phải là một số cân nhắc về phần của nhà phát triển.

Trong thực tế, không "đơn giản" chương trình tính tham khảo sẽ bao giờ được hoàn toàn khả thi mà không cần một số lượng tư tưởng bởi nhà phát triển ứng dụng (để tránh tham chiếu vòng tròn, vv)

0

Bởi vì thu gom rác trong các JVM hiện đại không còn theo dõi số tham chiếu. Thuật toán này được sử dụng để dạy cách GC hoạt động, nhưng nó vừa là tài nguyên vừa tiêu tốn vừa dễ xảy ra lỗi (ví dụ: phụ thuộc cyclic).

+0

Tôi không nghĩ rằng bất kỳ JVM chính thống nào từng sử dụng tính tham chiếu. –

2

đếm tham khảo có những hạn chế sau:

  • Đó là RẤT xấu cho đa luồng hiệu suất (về cơ bản, tất cả các nhiệm vụ của một tham chiếu đối tượng phải được bảo vệ).
  • Bạn không thể chu kỳ miễn phí tự động
Các vấn đề liên quan