2008-11-23 27 views
31

Tôi cảm thấy như các nhà phát triển nói về rò rỉ bộ nhớ nhưng khi bạn hỏi họ điều đó có nghĩa là nhiều người không có ý tưởng. Để ngăn chặn những tình huống này, hãy quyết định một.Định nghĩa rò rỉ bộ nhớ tốt nhất

Hãy không định nghĩa Wikipedia ...

là gì định nghĩa tốt nhất của một bộ nhớ của bạn bị rò rỉcách tốt nhất để ngăn chặn chúng là gì?

+0

Tôi tin câu trả lời của Brian Gianforcaro là câu trả lời hay nhất và ngắn gọn nhất. – Foredecker

+0

Tại sao bạn không chấp nhận định nghĩa của Wikipedia? –

+0

@Joshua Swink: Bởi vì đó sẽ là cảnh sát trong câu trả lời. :) – Spoike

Trả lời

34

Có hai định nghĩa (ít nhất là đối với tôi):

nét Naive: Thất bại trong việc phát hành unreachable nhớ, mà không còn có thể được phân bổ một lần nữa bằng phương pháp bất kỳ trong thực hiện các quá trình Cấp phát. Điều này chủ yếu có thể được chữa khỏi bằng cách sử dụng các kỹ thuật GC (Garbage Collection) hoặc được phát hiện bởi các công cụ tự động.

Định nghĩa tinh tế: Không thể phát hành có thể truy cập bộ nhớ không còn cần thiết để chương trình hoạt động bình thường. Điều này gần như không thể phát hiện với các công cụ tự động hoặc bởi các lập trình viên không quen thuộc với mã. Mặc dù về mặt kỹ thuật, nó không phải là một sự rò rỉ, nó có những tác động tương tự như cái ngây thơ. Đây không phải là ý tưởng của riêng tôi mà thôi. Bạn có thể bắt gặp các dự án được viết bằng ngôn ngữ thu thập rác nhưng vẫn đề cập đến việc sửa lỗi rò rỉ bộ nhớ trong các thay đổi của chúng.

+1

Có thể tìm thấy rò rỉ bộ nhớ trong danh mục "Tinh tế" khá dễ dàng với http://www.eclipse.org/mat. – kohlerm

4

Definition: Thất bại trong việc giải phóng bộ nhớ sau khi giao

Mozilla có page lớn vào các công cụ để theo dõi xuống rò rỉ bộ nhớ.

+0

Đó chỉ là rò rỉ nếu đó là bộ nhớ bạn không cần nữa. –

+0

Đúng, chắc chắn là một cảnh tượng của chính tôi. Tôi nhận thấy bạn cũng ở Rochester, NY .. thế giới nhỏ bé. –

+0

Liên kết không hoạt động. Bạn có thể cập nhật liên kết không? –

4

Quá trình trong đó tài nguyên bộ nhớ được cấp phát và không được phát hành đúng cách một lần không còn cần thiết, thường được giới thiệu thông qua thực hành mã hóa kém.

Có các cách được tích hợp sẵn trong một số ngôn ngữ để giúp ngăn chặn chúng, mặc dù cách tốt nhất để tránh chúng là thông qua việc quan sát cẩn thận các đường dẫn thực thi mã và đánh giá mã. Việc giữ các phương pháp ngắn gọn và độc đáo nhằm giúp giữ cho việc sử dụng tài nguyên chặt chẽ và ít bị mất trong việc trộn lẫn.

1

Bộ nhớ không được phân phối khi không còn cần thiết nữa và không còn "có thể truy cập" được nữa. Ví dụ, trong mã không được quản lý, nếu tôi sử dụng "mới" để khởi tạo một đối tượng, nhưng tôi không sử dụng "xóa" khi tôi thực hiện với nó (và con trỏ của tôi đã đi ra khỏi phạm vi hoặc một cái gì đó).

Cách tốt nhất để ngăn chặn chúng có thể phụ thuộc vào người bạn hỏi và ngôn ngữ bạn đang sử dụng. Bộ sưu tập rác là một giải pháp tốt cho nó, tất nhiên, nhưng có thể có một số chi phí liên quan đến điều này, mà không phải là một việc lớn trừ khi bạn thực hiện là mối quan tâm chính của bạn. Việc thu gom rác có thể không luôn luôn có sẵn, một lần nữa, tùy thuộc vào ngôn ngữ bạn đang sử dụng.

Cách khác, bạn có thể đảm bảo bạn đã xóa đúng và/hoặc trình phá hủy. Có rất nhiều phương pháp và công cụ để phát hiện rò rỉ bộ nhớ là tốt, nhưng điều này sẽ phụ thuộc vào ngôn ngữ và/hoặc IDE bạn đang sử dụng.

1

Có hai cách có thể xác định rò rỉ bộ nhớ. Trước tiên, nếu dữ liệu không được giải phóng khi không có bất kỳ tham chiếu nào đến nó, dữ liệu đó không thể truy cập được (trừ khi bạn có một số con trỏ bị hỏng hoặc đọc qua dữ liệu trong bộ đệm hoặc thứ gì đó). Về cơ bản, nếu bạn không giải phóng/xóa dữ liệu được phân bổ trên heap, nó sẽ trở thành không sử dụng được và đơn giản là lãng phí bộ nhớ.

Có thể có trường hợp con trỏ bị mất nhưng dữ liệu vẫn có thể truy cập được. Ví dụ, nếu bạn lưu trữ con trỏ trong một int, hoặc lưu trữ một bù đắp cho con trỏ (sử dụng số học con trỏ), bạn vẫn có thể lấy lại con trỏ ban đầu.

Trong định nghĩa đầu tiên này, dữ liệu được xử lý bởi người thu gom rác, theo dõi số tham chiếu đến dữ liệu.

Thứ hai, bộ nhớ cơ bản bị rò rỉ nếu bộ nhớ không được giải phóng/xóa khi sử dụng lần cuối. Nó có thể được tham chiếu, và ngay lập tức có thể miễn phí, nhưng sai lầm đã được thực hiện không làm như vậy. Có thể có một lý do hợp lệ (ví dụ: trong trường hợp một destructor có một số tác dụng phụ lạ), nhưng điều đó cho thấy thiết kế chương trình xấu (theo ý kiến ​​của tôi).

Loại rò rỉ bộ nhớ thứ hai này thường xảy ra khi viết các chương trình nhỏ sử dụng tệp IO. Bạn mở tệp, ghi dữ liệu của bạn, nhưng không đóng nó khi bạn đã hoàn tất. FILE * có thể vẫn nằm trong phạm vi và dễ dàng đóng được. Một lần nữa, có thể có một số lý do để làm điều này (chẳng hạn như khóa ghi truy cập bởi các chương trình khác), nhưng với tôi đó là một lá cờ của thiết kế xấu. Trong định nghĩa thứ hai này, dữ liệu không được xử lý bởi người thu gom rác, trừ khi trình biên dịch/thông dịch viên thông minh (hoặc câm) đủ để biết nó sẽ không được sử dụng nữa, và việc giải phóng dữ liệu sẽ không gây ra bất kỳ tác dụng phụ.

+0

Có, tôi đã nhấn nhiều chương trình mà không đóng một tập tin xử lý khi họ cần. Tôi thậm chí đã có một trao đổi nhiều tin nhắn với một người nghĩ rằng viết/đổi tên/đóng là lập trình chấp nhận được kể từ khi bạn nhận được đi với nó trên một hệ thống tập tin Windows. –

16

Bộ nhớ phân bổ không thể sử dụng được vì tham chiếu đến nó đã bị mất.

+4

Tôi thích nó, nhưng tôi không nghĩ nó khá chính xác.Ngay cả trong các hệ thống gc, đôi khi mọi thứ được gọi là "rò rỉ" bởi vì mặc dù bộ nhớ vẫn có thể truy cập, nó "không nên", bởi vì nó không còn cần thiết nữa. –

+2

Tôi nghĩ rằng đây là một trong những tốt nhất - tài liệu tham khảo để bộ nhớ có thể bị mất ngay cả trong các ngôn ngữ với bộ sưu tập rác. – Foredecker

+0

Bạn không phải mất tham chiếu đến bộ nhớ bị rò rỉ. Nếu bạn không cần bộ nhớ nữa nhưng bạn không giải quyết nó, ngay cả khi bạn giữ một tham chiếu đến nó xung quanh, nó là một rò rỉ bộ nhớ trong cuốn sách của tôi. –

-5

chỉnh sửa: Câu trả lời này sai. Tôi để nó như là một ví dụ về việc dễ bị nhầm lẫn với điều gì đó bạn nghĩ bạn biết rất rõ. Cảm ơn mọi người đã chỉ ra sai lầm của tôi.

Rò rỉ bộ nhớ là: Lỗi lập trình. Phần mềm của bạn mượn một số bộ nhớ từ hệ thống, sử dụng nó, và sau đó không trả lại nó cho hệ thống khi nó đã kết thúc. Điều này có nghĩa rằng đoạn bộ nhớ cụ thể đó không bao giờ có thể được sử dụng bởi bất kỳ chương trình nào khác cho đến khi hệ thống được khởi động lại. Nhiều rò rỉ như vậy có thể sử dụng hết tất cả bộ nhớ có sẵn, dẫn đến một hệ thống hoàn toàn vô dụng.

Để tránh rò rỉ bộ nhớ, hãy thực hành RIIA và luôn kiểm tra phần mềm của bạn. Có rất nhiều công cụ có sẵn cho công việc này.

+0

Tôi không biết về bất kỳ hệ điều hành hiện đại nào không trả lại tất cả bộ nhớ của ứng dụng vào danh sách miễn phí của hệ thống ngay khi chấm dứt. –

+0

Tôi chỉ với một số người. Tất cả bộ nhớ của chương trình được trả về hệ thống khi quá trình này bị giết. Vẫn còn dữ liệu ở đó, có thể bao gồm dữ liệu bộ nhớ cache từ các tệp đã mở, nhưng đó là tất cả được xử lý bởi hệ điều hành, chứ không phải chính chương trình. – strager

+0

Các bạn rõ ràng chưa bao giờ làm việc trên các thiết bị nhúng. –

1

Memory Leak: Không nhớ miễn phí mà bạn không còn cần trước khi một trong hai:

  • Chương trình chấm dứt
  • bộ nhớ bổ sung được phân bổ

Cách tốt nhất để ngăn chặn rò rỉ bộ nhớ: Bộ nhớ miễn phí ngay khi không còn cần thiết nữa.

+0

Giải phóng bộ nhớ trước khi chấm dứt là một sự cố. Đó là bộ nhớ bị mất trong khi chương trình vẫn chạy mà gây ra vấn đề. –

+0

Bạn, với tư cách là lập trình viên của một chương trình, không thể giải phóng bộ nhớ được cấp phát bởi chương trình của bạn sau khi chương trình đã kết thúc. Nó chỉ đơn giản là ngoài tầm kiểm soát của bạn. Vì vậy, điểm đầu tiên là dư thừa. Không quan trọng nếu bạn cấp thêm bộ nhớ sau khi bạn đã bắt đầu bị rò rỉ. – strager

+0

Về điểm đầu tiên, nếu bạn không giải phóng bộ nhớ trước khi ứng dụng chấm dứt bạn đứng để tạo ra rò rỉ bộ nhớ trong phần lớn các máy tính đang tồn tại (gợi ý: thế giới không phải là PC). –

1

Tất cả các định nghĩa đưa ra ở đây (tại thời điểm tôi viết này, chúng tôi đã nhận được câu trả lời tốt hơn kể từ khi) thất bại trong việc giải quyết một trường hợp đường biên giới:

Bạn có một singleton mà cấp phát bộ nhớ khi tạo và bộ nhớ này thường được tổ chức miễn là chương trình đang chạy mặc dù việc sử dụng hiện tại được thực hiện và nó không biết liệu bất kỳ sử dụng trong tương lai sẽ bao giờ được thực hiện hay không. Điều này thường được thực hiện bởi vì chi phí của việc tái tạo nó.

Do tiêu chuẩn "không tự do khi được thực hiện với nó", điều này sẽ được coi là rò rỉ và tôi đã thấy các công cụ báo cáo rò rỉ gọi những thứ đó bị rò rỉ khi bộ nhớ vẫn đang được sử dụng. (Và trên thực tế, mã có thể không chứa mã có khả năng làm sạch đối tượng.)

Tuy nhiên, tôi đã gặp phải mã này trong thư viện trình biên dịch trước khi chi phí tái tạo đối tượng không phải là tuyệt vời.

Rò rỉ hay không?

+0

Singletons bị rò rỉ bộ nhớ theo định nghĩa - đây chỉ là một trong những lý do bạn không bao giờ nên sử dụng chúng –

+0

Điều này thiếu khía cạnh _unintentional_ của rò rỉ bộ nhớ. Và một singleton, có thể có một phương thức giải phóng giải phóng bộ nhớ được cấp phát. – philant

+0

Tôi sẽ chỉ định nghĩa một thứ gì đó là "rò rỉ bộ nhớ" nếu nó gây ra một chương trình có thể xử lý chuỗi đầu vào vô hạn bằng cách sử dụng một lượng bộ nhớ bị giới hạn, thay vào đó yêu cầu bộ nhớ không bị chặn. Một singleton yêu cầu một lượng lưu trữ giới hạn sẽ không gây ra rò rỉ bộ nhớ. – supercat

1

w:

Trong khoa học máy tính, một rò rỉ bộ nhớ là một loại đặc biệt tiêu thụ bộ nhớ không chủ ý bởi một chương trình máy tính mà chương trình bị lỗi để giải phóng bộ nhớ khi không còn cần thiết. Tình trạng này thường là kết quả của một lỗi trong một chương trình ngăn không cho nó giải phóng bộ nhớ mà nó không còn cần nữa.

+0

Đợi một chút, Wikipedia trích dẫn stackoverflow trong định nghĩa của nó .... Tôi dám chắc rằng định nghĩa tham chiếu vòng tròn! – Jon

1

Dưới đây là một số kỹ thuật để ngăn ngừa/phát hiện rò rỉ bộ nhớ:

  1. xem xét thuật toán của bạn về tiêu thụ bộ nhớ. Người trả lời khác đã đề cập đến thực tế là bạn không phải mất con trỏ đến một mục được cấp phát để bộ nhớ bị rò rỉ. Ngay cả khi việc triển khai của bạn không chứa lỗi con trỏ, bạn vẫn có thể bị rò rỉ bộ nhớ nếu bạn giữ các mục được phân bổ lâu sau khi bạn thực sự cần chúng.

  2. Hồ sơ ứng dụng của bạn. Bạn có thể sử dụng các công cụ gỡ lỗi bộ nhớ như Valgrind hoặc Purify để tìm các lỗ rò.

  3. Kiểm tra hộp đen. Xem điều gì sẽ xảy ra với mã được biên dịch của bạn sau khi bạn nạp các tập dữ liệu lớn hoặc cho phép nó chạy trong một khoảng thời gian dài. Xem nếu dấu chân bộ nhớ của nó có xu hướng phát triển không có giới hạn.