Tôi đã đọc bài viết này về chủ đề này, nhưng tôi không thực sự hiểu nó. Xin vui lòng cho tôi một số lời khuyên cùng với các ví dụ khi mô tả các khái niệm.
Tôi đã đọc bài viết này về chủ đề này, nhưng tôi không thực sự hiểu nó. Xin vui lòng cho tôi một số lời khuyên cùng với các ví dụ khi mô tả các khái niệm.
Câu trả lời:
Java cung cấp hai loại / lớp đối tượng tham chiếu khác nhau : mạnh và yếu . Đối tượng tham chiếu yếu có thể được chia thành mềm và ảo .
Hãy đi từng điểm một.
Đối tượng tham khảo mạnh
StringBuilder builder = new StringBuilder();
Đây là loại / lớp mặc định của Đối tượng tham chiếu, nếu không được chỉ định khác: builder
là Đối tượng tham chiếu mạnh. Loại tham chiếu này làm cho đối tượng được tham chiếu không đủ điều kiện cho GC. Đó là, bất cứ khi nào một đối tượng được tham chiếu bởi một chuỗi các Đối tượng tham chiếu mạnh , nó không thể được thu gom rác.
Đối tượng tham khảo yếu
WeakReference<StringBuilder> weakBuilder = new WeakReference<StringBuilder>(builder);
Đối tượng tham chiếu yếu không phải là loại / lớp mặc định của Đối tượng tham chiếu và để được sử dụng, chúng phải được chỉ định rõ ràng như trong ví dụ trên. Loại tham chiếu này làm cho đối tượng tham chiếu đủ điều kiện cho GC. Đó là, trong trường hợp tham chiếu duy nhất có thể truy cập được cho StringBuilder
đối tượng trong bộ nhớ, trên thực tế, là tham chiếu yếu, thì GC được phép thu gom rác StringBuilder
đối tượng. Khi một đối tượng trong bộ nhớ chỉ có thể truy cập được bằng các Đối tượng tham chiếu yếu, nó sẽ tự động đủ điều kiện cho GC.
Mức độ yếu
Hai mức độ yếu khác nhau có thể được liệt kê: mềm và ảo .
Một mềm Object Reference cơ bản là một Object Reference yếu mà hài cốt trong bộ nhớ một cắn hơn: bình thường, nó chống lại chu kỳ GC cho đến khi không nhớ đã có sẵn và có nguy cơOutOfMemoryError
(trong trường hợp đó, nó có thể được loại bỏ).
Mặt khác, Đối tượng tham chiếu ảo chỉ hữu ích khi biết chính xác khi nào một đối tượng đã được xóa khỏi bộ nhớ một cách hiệu quả: thông thường chúng được sử dụng để sửa chữa hành vi hồi sinh / hồi sinh kỳ lạ () vì chúng thực sự không trả lại đối tượng chỉ giúp theo dõi sự hiện diện bộ nhớ của họ .
Đối tượng tham chiếu yếu là lý tưởng để thực hiện các mô-đun bộ đệm. Trong thực tế, một loại trục xuất tự động có thể được thực hiện bằng cách cho phép GC dọn sạch các vùng nhớ bất cứ khi nào các đối tượng / giá trị không thể truy cập được bằng chuỗi tham chiếu mạnh. Một ví dụ là WeakHashMap giữ lại các khóa yếu.
Tham khảo yếu:
Một tham chiếu yếu, đơn giản chỉ là, một tham chiếu không đủ mạnh để buộc một đối tượng ở lại trong bộ nhớ. Tài liệu tham khảo yếu cho phép bạn tận dụng khả năng của người thu gom rác để xác định khả năng tiếp cận cho bạn, vì vậy bạn không phải tự làm điều đó.
Tham khảo mềm:
Một tài liệu tham khảo mềm giống hệt như một tài liệu tham khảo yếu, ngoại trừ việc nó ít háo hức vứt bỏ đối tượng mà nó đề cập đến. Một đối tượng chỉ có thể tiếp cận yếu (tham chiếu mạnh nhất đến nó là WeakReferences) sẽ bị loại bỏ ở chu kỳ thu gom rác tiếp theo, nhưng một đối tượng có thể tiếp cận nhẹ thường sẽ tồn tại trong một thời gian.
Tham chiếu ma:
Một tham chiếu ảo khá khác so với SoftReference hoặc WeakReference. Độ bám của nó đối với đối tượng của nó rất khó để bạn thậm chí không thể truy xuất đối tượng - phương thức get () của nó luôn trả về null. Việc sử dụng duy nhất cho một tham chiếu như vậy là theo dõi khi nào nó được đưa vào ReferenceQueue, vì tại thời điểm đó, bạn biết đối tượng mà nó chỉ ra đã chết.
Văn bản này được trích xuất từ: https://weblogs.java.net/blog/2006/05/04/under Hiểu-weak-report
Sự khác biệt đơn giản giữa SoftReference
và WeakReference
được cung cấp bởi Nhà phát triển Android .
Sự khác biệt giữa a SoftReference
và a WeakReference
là thời điểm mà quyết định được đưa ra để làm rõ và ghi lại tham chiếu:
A SoftReference
nên được xóa và xử lý càng muộn càng tốt, trong trường hợp VM có nguy cơ hết bộ nhớ.
A WeakReference
có thể bị xóa và mê hoặc ngay khi được biết là tham chiếu yếu.
Ba thuật ngữ mà bạn đã sử dụng hầu hết liên quan đến tính đủ điều kiện của Object để thu gom Rác.
Tham chiếu yếu :: Đây là một tham chiếu không đủ mạnh để buộc đối tượng ở lại trong bộ nhớ. Đó là ý tưởng của người thu gom rác để thu thập đối tượng đó để thu gom rác. Bạn không thể buộc GC không thu thập nó .
Tham chiếu mềm :: Nó ít nhiều giống như tham chiếu yếu. Nhưng bạn có thể nói rằng nó giữ đối tượng mạnh hơn một chút so với tham chiếu yếu từ bộ sưu tập rác.
Nếu người thu gom Rác thu thập tham chiếu yếu trong chính vòng đời đầu tiên, nó sẽ thu thập tham chiếu mềm trong chu kỳ thu gom Rác tiếp theo.
Tham chiếu mạnh :: Nó chỉ đối diện với hai loại tài liệu tham khảo ở trên. Họ ít thích thu gom rác (Hầu hết chúng không bao giờ được thu gom.)
Bạn có thể tham khảo liên kết sau để biết thêm thông tin:
http://docs.oracle.com/javase/1.4.2/docs/api/java/lang/ref/Reference.html
Bài viết này có thể siêu hữu ích để hiểu các tài liệu tham khảo mạnh, mềm, yếu và ảo.
Để cho bạn một bản tóm tắt,
Nếu bạn có một tham chiếu mạnh đến một đối tượng, thì đối tượng đó không bao giờ có thể được thu thập / thu hồi bởi GC (Garbage Collector).
Nếu bạn chỉ có tài liệu tham khảo yếu đến một đối tượng (không có tham chiếu mạnh), thì đối tượng đó sẽ được thu hồi bởi GC trong chu trình GC tiếp theo.
Nếu bạn chỉ có các tham chiếu mềm đến một đối tượng (không có tham chiếu mạnh), thì đối tượng đó sẽ chỉ được thu hồi bởi GC khi JVM hết bộ nhớ.
Chúng tôi tạo các tham chiếu ảo đến một đối tượng để theo dõi khi nào đối tượng bị mê hoặc ReferenceQueue
. Một khi bạn biết rằng bạn có thể thực hiện hoàn thiện hạt mịn. (Điều này sẽ cứu bạn khỏi việc vô tình hồi sinh đối tượng dưới dạng tham chiếu ảo không cung cấp cho bạn người giới thiệu). Tôi muốn đề nghị bạn đọc này bài viết để có được chiều sâu chi tiết về việc này.
Vì vậy, bạn có thể nói rằng, các tài liệu tham khảo mạnh mẽ có sức mạnh tối thượng (không bao giờ có thể được thu thập bởi GC)
Tham chiếu mềm mạnh hơn tham chiếu yếu (vì chúng có thể thoát khỏi chu trình GC cho đến khi JVM hết bộ nhớ)
Các tham chiếu yếu thậm chí còn kém mạnh hơn các tham chiếu mềm (vì chúng không thể thoát khỏi bất kỳ chu trình GC nào và sẽ được thu hồi nếu đối tượng không có tham chiếu mạnh nào khác).
Nhà hàng tương tự
Bây giờ nếu bạn là một khách hàng mạnh mẽ (tương tự như tham chiếu mạnh), thì ngay cả khi một khách hàng mới đến nhà hàng hoặc những gì đã từng xảy ra, bạn sẽ không bao giờ rời khỏi bàn của mình (vùng nhớ trên đống). Người phục vụ không có quyền bảo bạn (hoặc thậm chí yêu cầu bạn) rời khỏi nhà hàng.
Nếu bạn là một khách hàng mềm (tương tự như tham chiếu mềm), thì nếu một khách hàng mới đến nhà hàng, người phục vụ sẽ không yêu cầu bạn rời khỏi bàn trừ khi không còn bàn trống nào khác để chứa khách hàng mới. (Nói cách khác, người phục vụ sẽ yêu cầu bạn rời khỏi bàn chỉ khi một khách hàng mới bước vào và không còn bàn nào khác cho khách hàng mới này)
Nếu bạn là một khách hàng yếu (tương tự như tham chiếu yếu), thì người phục vụ, theo ý muốn của anh ta, có thể (bất cứ lúc nào) yêu cầu bạn rời khỏi nhà hàng: P
4 độ tham chiếu - Strong, Weak, Soft, Phantom
Mạnh - là một loại tham chiếu, làm cho đối tượng được tham chiếu không đủ điều kiện cho GC. lớp xây dựng. ví dụ: StringBuilder
Yếu - là một tài liệu tham khảo đủ điều kiện cho GC.
Mềm - là một loại tài liệu tham khảo có đối tượng đủ điều kiện cho GC cho đến khi bộ nhớ có sẵn. Tốt nhất cho bộ nhớ cache hình ảnh. Nó sẽ giữ chúng cho đến khi bộ nhớ có sẵn.
Phantom - là một loại tài liệu tham khảo có đối tượng đủ điều kiện trực tiếp cho GC. Chỉ được sử dụng để biết khi nào một đối tượng được xóa khỏi bộ nhớ.
sử dụng:
Cho phép bạn xác định khi một đối tượng được xóa chính xác khỏi bộ nhớ.
khi
finalize()
phương thức bị quá tải, thì GC có thể không xảy ra một cách kịp thời cho các đối tượng đủ điều kiện của hai lớp. Vì vậy, tham chiếu ảo làm cho chúng đủ điều kiện cho GC trước đófinalize()
, là lý do tại sao bạn có thể nhận OutOfMemoryErrors ngay cả khi hầu hết các heap là rác.
Tham chiếu yếu là lý tưởng để thực hiện các mô-đun bộ đệm.
Đây là các tài liệu tham khảo đối tượng thường xuyên của bạn mà chúng tôi mã hàng ngày:
Employee emp = new Employee();
Biến số emp emp giữ một tham chiếu mạnh đến một đối tượng Nhân viên và các đối tượng có thể truy cập thông qua bất kỳ chuỗi tham chiếu mạnh nào không đủ điều kiện để thu gom rác. Thông thường, đây là những gì bạn muốn nhưng không phải luôn luôn. Bây giờ, giả sử chúng tôi đang tìm nạp rất nhiều nhân viên từ cơ sở dữ liệu trong bộ sưu tập hoặc bản đồ và chúng tôi cần xử lý chúng thường xuyên, vì vậy để giữ hiệu suất, chúng tôi sẽ giữ chúng trong bộ nhớ cache.
Theo như điều này là tốt nhưng bây giờ chúng tôi cần dữ liệu khác nhau và chúng tôi không cần những đối tượng Nhân viên đó và chúng không được tham chiếu từ bất cứ đâu ngoại trừ bộ đệm. Điều này gây ra rò rỉ bộ nhớ vì các đối tượng này không được sử dụng nhưng vẫn không đủ điều kiện cho bộ sưu tập rác và chúng tôi không thể xóa các đối tượng đó khỏi bộ đệm vì chúng tôi không có tham chiếu đến chúng? Vì vậy, ở đây, chúng ta cần làm trống toàn bộ bộ đệm một cách thủ công, điều này thật tẻ nhạt hoặc chúng ta có thể sử dụng các loại tham chiếu khác, ví dụ như Tài liệu tham khảo yếu.
Một tham chiếu yếu không ghim một đối tượng vào bộ nhớ và sẽ là GC'd trong chu trình GC tiếp theo nếu không được tham chiếu từ các tham chiếu khác. Chúng ta có thể sử dụng lớp WeakReference do Java cung cấp để tạo ra loại bộ đệm bên trên, sẽ không lưu trữ các đối tượng không được tham chiếu từ nơi nào khác.
WeakReference<Cache> cache = new WeakReference<Cache>(data);
Để truy cập dữ liệu, bạn cần gọi cache.get (). Cuộc gọi để nhận này có thể trả về null nếu tham chiếu yếu là rác được thu thập: bạn phải kiểm tra giá trị được trả về để tránh NPE. Java cung cấp các bộ sưu tập sử dụng các tham chiếu yếu, ví dụ, lớp WeakHashMap lưu trữ các khóa (không phải giá trị) làm các tham chiếu yếu. Nếu khóa là GC'd thì giá trị cũng sẽ tự động bị xóa khỏi bản đồ.
Vì các tham chiếu yếu cũng là các đối tượng, chúng tôi cần một cách để dọn sạch chúng (chúng không còn hữu ích khi đối tượng mà chúng tham chiếu đã là GC'd). Nếu bạn chuyển ReferenceQueue vào hàm tạo cho tham chiếu yếu thì trình thu gom rác sẽ nối thêm tham chiếu yếu đó vào ReferenceQueue trước khi chúng được hoàn thành hoặc GC'd. Bạn có thể định kỳ xử lý hàng đợi này và đối phó với các tài liệu tham khảo đã chết.
SoftReference giống như WeakReference nhưng ít có khả năng là rác được thu thập. Tài liệu tham khảo mềm được xóa theo quyết định của người thu gom rác theo nhu cầu bộ nhớ. Máy ảo đảm bảo rằng tất cả các tham chiếu mềm đến các đối tượng có thể tiếp cận mềm sẽ bị xóa trước khi nó ném OutOfMemoryError.
Tham chiếu Phantom là yếu nhất trong tất cả các loại tham chiếu, việc gọi get trên chúng sẽ luôn trả về null. Một đối tượng được tham chiếu ảo sau khi nó được hoàn thành, nhưng trước khi bộ nhớ được phân bổ của nó được lấy lại, Trái ngược với các tham chiếu yếu được xử lý trước khi chúng được hoàn thiện hoặc các tham chiếu Phantom của GC hiếm khi được sử dụng.
Vậy chúng hữu ích như thế nào? Khi bạn xây dựng một tham chiếu ảo, bạn phải luôn vượt qua trong ReferenceQueue. Điều này chỉ ra rằng bạn có thể sử dụng một tham chiếu ảo để xem khi nào đối tượng của bạn là GC'd.
Này, vì vậy, nếu các tham chiếu yếu được xử lý khi chúng được xem là hoàn thiện nhưng chưa phải là GC, chúng ta có thể tạo một tham chiếu mạnh mới cho đối tượng trong khối hoàn thiện và ngăn không cho đối tượng bị GC. Đúng, bạn có thể nhưng có lẽ bạn không nên làm điều này. Để kiểm tra trường hợp này, chu trình GC sẽ xảy ra ít nhất hai lần cho mỗi đối tượng trừ khi đối tượng đó chỉ có thể truy cập được bằng tham chiếu ảo. Đây là lý do tại sao bạn có thể hết đống ngay cả khi bộ nhớ của bạn chứa nhiều rác. Tài liệu tham khảo Phantom có thể ngăn chặn điều này.
Bạn có thể đọc thêm về bài viết của tôi Các loại tài liệu tham khảo trong Java (Mạnh, Mềm, Yếu, Phantom) .