2011-07-12 23 views
5

thể trùng lặp:
Creating a memory leak with JavaRò rỉ bộ nhớ có hoàn toàn vắng mặt trong các ứng dụng Java không?

Có một "rác Collector" trong Java, nhưng điều này không có nghĩa là rò rỉ bộ nhớ là hoàn toàn vắng mặt trong một ứng dụng Java? Nếu không, làm thế nào và tại sao chúng xảy ra?

Tôi quan tâm hơn đến các tình huống trong các ứng dụng sử dụng JavaSE.

+0

Có một chủ đề [ở đây] (http://stackoverflow.com/q/6470651/3009) thảo luận cách tạo rò rỉ bộ nhớ trong java. – highlycaffeinated

Trả lời

14

Rò rỉ không có bộ nhớ vẫn có thể tồn tại trong Java. Họ chỉ là một "loại khác".

Wiki: Memory Leak

Một rò rỉ bộ nhớ, khoa học máy tính (hoặc rò rỉ, trong bối cảnh này), xảy ra khi một chương trình máy tính tiêu thụ bộ nhớ nhưng là không thể phát hành nó [ký ức] trở lại hệ điều hành.

Trong trường hợp của Java nó (thường) là khi một không sử dụng đối tượng/không cần thiết không bao giờ làm đủ điều kiện để khai hoang. Ví dụ: một đối tượng có thể được lưu trữ trong Danh sách chung và không bao giờ bị xóa ngay cả khi đối tượng đó không bao giờ được truy cập sau này. Trong trường hợp này JVM sẽ không giải phóng đối tượng/bộ nhớ - , không thể - vì đối tượng có thể cần sau, ngay cả khi nó không bao giờ là.

(Là một sang một bên, một số đối tượng, chẳng hạn như ByteBuffers phân bổ trực tiếp cũng tiêu thụ "ra khỏi JVM đống" bộ nhớ mà có thể không được khai hoang một cách kịp thời do bản chất của finalizers và áp lực bộ nhớ.)

Trong trường hợp của Java, "rò rỉ bộ nhớ" là một vấn đề ngữ nghĩa và không quá nhiều vấn đề "không thể giải phóng trong bất kỳ trường hợp nào". Tất nhiên, với mã JNI/JNA lỗi, tất cả các cược sẽ tắt ;-)

Mã hóa vui vẻ.

+2

Theo dõi, không có bộ thu gom rác nào có thể thu hồi tất cả bộ nhớ không sử dụng. Không thể xây dựng một GC có thể phát hiện xem một phần bộ nhớ nào đó sẽ không bao giờ được sử dụng lại hay không, vì vậy hầu hết các GC đều sử dụng liệu bộ nhớ có thể truy cập được ** như một đại diện hay không. – templatetypedef

+0

cảm ơn pst phản hồi nhanh. vấn đề mà bạn đã đề cập là đúng, nhưng nhiều hơn vì thực hành lập trình (xấu), đúng không? Giả sử có một số đối tượng trong bộ nhớ "thực sự" đủ điều kiện để cải tạo, chúng có chắc chắn sẽ được JVM khai hoang không? chắc chắn? – Bhushan

+1

@ 10101010 Các đối tượng có thể khôi phục, những đối tượng không thể truy cập mạnh từ gốc, ** sẽ được xác nhận lại "tại một số điểm" **, có. Tuy nhiên, trong trường hợp các đối tượng phát hành bộ nhớ "bản địa" trong trình hoàn thiện, có thể bộ nhớ ("gốc") không được phát hành đủ nhanh - ngay cả khi nó * có thể là * - và do đó có thể dẫn đến một [sớm] OOM. –

1

Rò rỉ bộ nhớ trong java rất có thể. Here is a good article which has an example using core java. Về cơ bản, rò rỉ bộ nhớ xảy ra trong java khi bộ thu gom rác không thể lấy lại một đối tượng vì ứng dụng giữ một tham chiếu đến nó rằng nó sẽ không phát hành, mặc dù chính đối tượng đó có thể không còn được sử dụng nữa. Cách dễ nhất để tạo rò rỉ bộ nhớ trong java là để ứng dụng của bạn giữ một tham chiếu đến một cái gì đó, nhưng không sử dụng nó.

Trong ví dụ, đối tượng không sử dụng là Danh sách tĩnh và việc thêm những thứ vào danh sách đó cuối cùng sẽ khiến JVM hết bộ nhớ. Bộ sưu tập tĩnh là một nguồn "rò rỉ" khá phổ biến, vì chúng thường tồn tại lâu dài và có thể thay đổi được.

2

Phụ thuộc vào cách bạn xác định rò rỉ bộ nhớ.

Nếu bạn đặc biệt có nghĩa là đã cấp phát bộ nhớ không còn được tham chiếu bởi một số bộ nhớ gốc, thì không, bộ thu gom rác cuối cùng sẽ xóa sạch tất cả những bộ nhớ đó.

Nếu bạn muốn nói chung có dấu chân bộ nhớ của bạn phát triển mà không bị ràng buộc, điều đó có thể dễ dàng thực hiện được. Chỉ cần có một số bộ sưu tập được tham chiếu bởi một trường tĩnh và liên tục được thêm vào.

1

Hiện có một vài phản hồi tốt. Tôi không muốn tạo lại những bài viết đó, vì vậy tôi sẽ chỉ thêm một điều mà hầu hết mọi người không nghĩ đến liên quan đến chủ đề này là rò rỉ trong mã nguồn gốc chạy qua JNI. Mã nguồn gốc chạy qua JNI sử dụng không gian heap của JVM để cấp phát bộ nhớ. Vì vậy, nếu ứng dụng của bạn sử dụng mã gốc chạy qua JNI có rò rỉ, ứng dụng của bạn sẽ bị rò rỉ.

1

Bất kỳ đối tượng nào có một hoặc nhiều tham chiếu sống sẽ không được thu thập rác. Vì vậy, miễn là một số biến (hoặc tĩnh, trong đống, hoặc trong ngăn xếp) đề cập đến một đối tượng, đối tượng đó sẽ tiếp tục chiếm không gian bộ nhớ không thể phục hồi.

Tài nguyên không được tiết lộ (như ổ cắm, kết nối JDBC, v.v.) và các bộ sưu tập tĩnh liên tục phát triển là một số nhà sản xuất bị rò rỉ nổi tiếng hơn.

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