2010-02-25 27 views
5

Rò rỉ bộ nhớ là khi có bộ nhớ không sử dụng trong ứng dụng và GC có thể thu thập nó, thông thường nó xảy ra nếu một số trong ứng dụng chúng tôi giữ tham chiếu không mong muốn mạnh mẽ của đối tượng và GC sẽ tìm thấy đường dẫn (Trực tiếp và gián tiếp) nó có thể giải phóng đối tượng này, nhưng tất cả điều này là đúng về kiểu tham chiếu có nghĩa là trong việc cấp phát bộ nhớ Heap.Có thể rò rỉ bộ nhớ có thể xảy ra ở ngăn xếp trong .NET không?

Nhưng những gì về ngăn xếp Và như xa tôi biết GC sẽ không chịu trách nhiệm để làm sạch ngăn xếp nó sẽ tự động làm sạch khi chức năng sẽ trở lại. Vì vậy, câu hỏi của tôi là có bất kỳ cơ hội mà rò rỉ bộ nhớ sẽ xảy ra trong ngăn xếp cũng ?, nếu có thì tại kịch bản nào và thực hành tốt nhất để tránh loại rò rỉ là gì.

Trả lời

2

Nếu bạn đang viết các hàm đệ quy giữ tham chiếu ngăn xếp cục bộ với dữ liệu lớn không cần thiết trong các cuộc gọi đệ quy, thì đây là một loại rò rỉ không gian, nhưng rất không bình thường khi có vấn đề này thực hành.

Tổng quát hơn, nếu bạn có một cái gì đó giống như

Main() { 
    var s = ReadInAGiganticString(); // say 10 Megs long 
    Server(s.Substring(0,5));   // but I only care about first 5 chars 
} 
Server(s) { 
    while(true) { ... }    // but 10M is on stack forever 
} 

thì đây là một loại ngăn xếp không gian-rò rỉ, nhưng một lần nữa, nó là khó xảy ra trong thực tế. Việc sửa chữa rất dễ dàng:

Main() { 
    var s = ReadInAGiganticString(); 
    var t = s.Substring(0,5); 
    s = null;       // the fix 
    Server(t); 
} 
Server(s) { 
    while(true) { ... } 
} 

Nói chung, nếu bạn có một biến khổng lồ trên ngăn xếp ngay trước khi cuộc gọi kéo dài lâu và biến không còn được sử dụng nữa, bạn có thể vô hiệu hóa nó để đảm bảo nó có thể được GC'd trước khi đi vào cuộc gọi 'dài'.

(Có thể là một ưu hoa có thể làm điều này cho bạn dựa trên phân tích reachability.)

Lưu ý rằng các câu trả lời trên là tài liệu tham khảo cho các đối tượng đống phân bổ được bắt nguồn từ trên stack. Mặt khác, nếu bạn có bộ nhớ phân bổ stack (ví dụ: một cấu trúc khổng lồ hoặc thingall stackalloc), thì việc sửa chữa không dễ dàng, nhưng điều này thậm chí còn hiếm hơn trong thực tế (ai đã tạo ra các cấu trúc khổng lồ?).

+1

Chỉ tham chiếu đến chuỗi nằm trên ngăn xếp, chính chuỗi đó nằm trên heap. –

0

Các biến được phân bổ trong ngăn xếp sẽ bị hủy sau khi khối kết thúc. Vì vậy, nó không phải là có thể rò rỉ bộ nhớ có thể tích luỹ. Thực hành trên giường là tạo biến chỉ được sử dụng trong một khối nhất định bên ngoài khối đó

0

Khi bạn nói GC không dọn dẹp ngăn xếp. Tuy nhiên, không gian được sử dụng bởi ngăn xếp được khai hoang trong thời gian thư giãn. Vì vậy, như ngăn xếp được popped con trỏ ngăn xếp được di chuyển "trở lại" và do đó không gian có thể được tái sử dụng.

Hết dung lượng ngăn xếp sẽ tăng StackOverflowException. Nó thường là do một lỗi lập trình với đệ quy không giới hạn.

0

Nếu không biết quá nhiều về nội bộ của .NET, tôi sẽ nói rằng nếu bạn có ngăn xếp rò rỉ, bạn sẽ có chương trình bị lỗi vì địa chỉ trả về hàm/phương thức cũng được lưu trữ trên ngăn xếp (rất có thể) .

Nếu ngăn xếp của bạn bị lệch hướng bằng cách nào đó bạn sẽ có vấn đề lớn hơn nhiều so với rò rỉ bộ nhớ.

Thông số phương pháp thường và giá trị trả về được lưu trữ trên ngăn xếp (nếu không được tối ưu hóa để được gửi qua thanh ghi cpu).

0

Không, miễn là bạn đang sử dụng mã an toàn, rò rỉ bộ nhớ không thể xảy ra cho các biến ngăn xếp.

1

Rò rỉ bộ nhớ có thể xảy ra nếu bạn không giải phóng tài nguyên không được quản lý một cách chính xác. Vì vậy, tôi sợ rằng nếu bạn gửi một đối tượng được quản lý đến một phương thức và đối tượng này bao bọc một tài nguyên không được quản lý và nó không giải phóng tài nguyên không được quản lý một cách chính xác thì sẽ có một rò rỉ bộ nhớ. Ngăn xếp sẽ giải phóng tham chiếu được quản lý nhưng tài nguyên không được quản lý sẽ vẫn hoạt động.

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