Go có bị rò rỉ bộ nhớ tinh vi giống như Java không?


89

Đây là sự thật:

  • ngôn ngữ Go có một bộ thu gom rác.

  • Java có một bộ sưu tập rác

  • rất nhiều chương trình Java bị rò rỉ bộ nhớ (tinh tế hoặc không)

Ví dụ về một chương trình Java bị rò rỉ bộ nhớ (không dành cho những người yếu tim, câu hỏi có thể làm lung lay niềm tin của bạn), hãy xem ở đây về một chương trình Java nhỏ có tên Tomcat thậm chí có nút "tìm rò rỉ": Có cách nào để tránh rò rỉ bộ nhớ không triển khai trong Tomcat?

Vì vậy, tôi đang tự hỏi: các chương trình được viết bằng Go có biểu hiện giống như loại rò rỉ bộ nhớ (tinh tế hay không) mà một số chương trình được viết bằng Java thể hiện?


29
"rất nhiều chương trình Java bị rò rỉ bộ nhớ (tinh tế hoặc không)" bạn có bất kỳ bằng chứng nào về "sự thật" này không hay đó chỉ là một điểm nói suông.
Peter Lawrey

17
@Webinator: Tôi nghĩ bạn cần đưa ra một ví dụ về một trong những "rò rỉ bộ nhớ tinh vi" mà "rất nhiều" chương trình Java mắc phải. Trừ khi bạn đang xác nhận một lỗi trong bộ thu gom rác, cách duy nhất để làm rò rỉ bộ nhớ trong Java thuần túy là giữ lại các tham chiếu mà bạn không còn sử dụng nữa, ví dụ bằng cách đưa các đối tượng vào một bộ sưu tập và không bao giờ xóa chúng khỏi bộ sưu tập đó. Nếu đây là loại rò rỉ mà bạn đang đề cập đến, thì không ngôn ngữ nào trên thế giới sẽ bảo vệ chống lại chúng, kể cả cờ vây.
JeremyP

14
Đây là những rò rỉ bộ nhớ mà tôi đã nói đến (+200 lượt ủng hộ, câu trả lời với +150 lượt ủng hộ, giải thích rất nhiều rò rỉ bộ nhớ Java thực tế): stackoverflow.com/questions/6470651/…
SyntaxT3rr0r

6
Tất nhiên các chương trình JAVA có rò rỉ bộ nhớ, chỉ cần quên đặt một số tham chiếu thành null khi bạn chấm lâu hơn cần chúng. Thường xuyên xảy ra trong các bộ sưu tập lớn liên tục (như bộ nhớ đệm), với mẫu thiết kế trình quan sát hoặc các biến cục bộ của luồng. Đây không phải là lý thuyết, tôi đã tự sửa một số lỗi rò rỉ bộ nhớ trong quá trình sản xuất. Và đây không phải là chống Java. Tôi là một nhà phát triển JAVA toàn thời gian trong hơn 5 năm, đã làm việc trên rất nhiều dự án khác nhau. Không nhận ra bạn có thể bị rò rỉ bộ nhớ trong JAVA (hoặc tất cả các ngôn ngữ hiện có khác) không phải là chủ nghĩa cuồng tín, mà là thiếu hiểu cách mọi thứ thực sự hoạt động.
Nicolas Bousquet,

6
Câu hỏi này có thể làm được nếu không có bộ phim và những bình luận về "chủ nghĩa fanboy", "làm lung lay niềm tin của ai đó" và những thứ tương tự. Esp. kể từ khi toàn bộ cuộc thảo luận trở thành "định nghĩa của tôi memory leaklà tốt hơn của bạn".
LAFK nói Hãy phục hồi Monica vào

Câu trả lời:


44

Bạn đang nhầm lẫn giữa các loại rò rỉ bộ nhớ ở đây.

Rò rỉ bộ nhớ dựa trên quản lý bộ nhớ rõ ràng, nghiêm trọng đã không còn trong Java (hoặc bất kỳ ngôn ngữ dựa trên GC nào khác). Những rò rỉ này là do mất hoàn toàn quyền truy cập vào các phần bộ nhớ mà không đánh dấu chúng là không sử dụng.

Hiện tượng "rò rỉ bộ nhớ" vẫn còn trong Java và mọi ngôn ngữ khác trên hành tinh này cho đến khi máy tính có thể đọc được suy nghĩ của chúng ta vẫn ở bên chúng ta và sẽ xảy ra trong tương lai gần. Những rò rỉ này là do mã / lập trình viên giữ các tham chiếu đến các đối tượng mà về mặt kỹ thuật không còn cần thiết. Đây là những lỗi logic cơ bản và không thể được ngăn chặn bằng bất kỳ ngôn ngữ nào bằng các công nghệ hiện tại.


23
Rò rỉ bộ nhớ chỉ đơn giản là khi bạn quên giải phóng bộ nhớ. Trong Java, điều này xảy ra khi bạn quên đặt tham chiếu thành null. Trong C ++, nó sẽ xảy ra nếu bạn quên gọi miễn phí. Cả hai đều là trường hợp rò rỉ bộ nhớ hợp lệ. Và vấn đề cơ bản là giống nhau, chương trình của bạn ngày càng tiêu tốn nhiều bộ nhớ hơn cho đến khi cuối cùng nó bị lỗi với lỗi OutOfMemory.
Nicolas Bousquet,

1
Mặc dù đúng là không có ngôn ngữ nào có thể ngăn lập trình viên tạo ra các lỗi logic như vậy, nhưng cũng đúng là một số lỗi như vậy tồn tại trong chính Java SDK (ví dụ: xem, trong java.util.logging.Levelđó có chứa một tĩnh riêng ArrayListmà trong đó tất cả các đối tượng như vậy được tạo được đặt trong quá trình xây dựng và từ đó chúng không bao giờ bị loại bỏ), điều này khiến việc tránh chúng khi lập trình Java khó hơn so với một số ngôn ngữ khác không chứa các sai sót như vậy
Jules

7
Tôi nghĩ OP đã hỏi về việc rò rỉ bộ nhớ của các đối tượng thực sự không thể truy cập được như trong câu trả lời được chấp nhận của câu hỏi được liên kết. Rò rỉ bộ nhớ là do tải lớp từ các luồng. -1
qbt937

1
Cũng có thể hình dung được rằng phân tích tĩnh có thể xác định xem các tham chiếu có tiếp tục tồn tại trong thời gian tồn tại hữu ích của chúng hay không - không cần đọc suy nghĩ.
Kyle Strand

1
@Amrit Không, trình thu gom rác thu thập bộ nhớ mà bạn không còn tham chiếu đến nữa. Không có cách nào để biết liệu bạn có thể xóa thứ gì đó mà bạn vẫn còn tham chiếu đến hay không.
Raphael Schmitz

19

Rất có thể các chương trình Go sẽ bị rò rỉ bộ nhớ. Việc triển khai hiện tại của Go có một bộ thu gom rác đánh dấu và quét đơn giản. Đây chỉ là giải pháp tạm thời và không phải là công cụ thu gom rác lâu dài. Xem trang này để biết thêm thông tin. Nhìn dưới tiêu đề Go Garbage Collector. Trang đó thậm chí còn có một liên kết đến mã cho phiên bản hiện tại nếu bạn thích.


1
Một trong những vấn đề của bộ thu thập dấu và quét trong Java là phân mảnh bộ nhớ. Mặc dù không phải là bộ nhớ về mặt kỹ thuật, nhưng nó có thể làm mất bộ nhớ khả dụng cho ứng dụng.
Peter Lawrey

9

'Rò rỉ bộ nhớ' là khi một phần bộ nhớ mà lập trình viên nghĩ rằng sẽ được giải phóng không được giải phóng. Điều này có thể xảy ra bằng bất kỳ ngôn ngữ nào, rác được thu gom hay không. Nguyên nhân thông thường trong các ngôn ngữ GC là giữ lại một tham chiếu bổ sung vào bộ nhớ.

"Ngôn ngữ không gây rò rỉ bộ nhớ, lập trình viên gây rò rỉ bộ nhớ".


8

Thu gom rác hay không, bạn có thể viết một chương trình bị rò rỉ bộ nhớ bằng Java, Go hoặc bất kỳ ngôn ngữ nào khác.

Garbage Collection thực hiện một số gánh nặng cho lập trình viên nhưng nó không ngăn chặn hoàn toàn việc rò rỉ.


4
Tôi biết rồi mà. Tôi đang nói cụ thể về những lỗi rò rỉ bộ nhớ khá tinh vi tồn tại trong Java ngay cả khi Java khó khăn, vào thời kỳ đầu, được tiếp thị như một ngôn ngữ mà lỗi rò rỉ bộ nhớ không tồn tại nhờ GC .
Cú phápT3rr0r

4
Xin lỗi vì điều đó không rõ ràng. Bạn đã nói "rất nhiều chương trình Java bị rò rỉ bộ nhớ (tinh tế hoặc không)".
jzd

3

Bạn đang trộn các mức trừu tượng ở đây: bộ nhớ bị rò rỉ là do lỗi trong thư viện (nơi các đối tượng tham chiếu lẫn nhau thông qua chuỗi 'a giữ tham chiếu đến b' cũng như sự đánh đổi trong việc triển khai bộ thu gom rác giữa hiệu quả và độ chính xác. Bạn muốn dành bao nhiêu thời gian để tìm ra các vòng lặp như vậy? Nếu bạn dành nhiều gấp đôi, bạn sẽ có thể phát hiện các vòng lặp dài gấp đôi.

Vì vậy, vấn đề rò rỉ bộ nhớ không phải là ngôn ngữ lập trình cụ thể, không có lý do gì mà bản thân GO phải tốt hơn hoặc tệ hơn Java.


1
Tôi không hoàn toàn đồng ý. Rò rỉ bộ nhớ là do Java có thể tự bắn vào chân và nó không nhất thiết liên quan đến lỗi thư viện. Rất nhiều lập trình viên viết chương trình chậm nhưng chắc chắn làm rò rỉ bộ nhớ trong Java và đó là lỗi của chính họ, không phải lỗi của thư viện. Ngoài ra, nếu chính xác thì Java GC đang đánh đổi thời gian / có thể bị rò rỉ, thì Go có thực hiện đánh đổi tương tự không?
Cú phápT3rr0r

1
và câu hỏi thực sự không phải là "tôi muốn dành bao nhiêu thời gian để tìm ra những vòng lặp như vậy?" Câu hỏi là "Các thông số kỹ thuật bắt buộc Go GC dành bao nhiêu thời gian cho các vòng lặp như vậy" , IMHO là một câu hỏi thú vị.
Cú phápT3rr0r

16
Chuỗi tham chiếu tuần hoàn không ngăn chặn việc thu gom rác trong Java.
Andy Thomas
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.