2014-04-22 23 views
8

Chúng tôi có dịch vụ cửa sổ 32 bit rò rỉ bộ nhớ - Ngoại lệ OutOfMemory được ném. Nó là .net 4.0 thực thi chạy trên windows server 2003. Trong khi gỡ rối các tệp kết xuất sự cố bằng cách sử dụng WinDbg, tôi thấy rằng hầu hết bộ nhớ thực sự được bảo lưu và không được cam kết. enter image description hereCó thể đặt trước bộ nhớ gây ra ngoại lệ Hết bộ nhớ

Như bạn có thể thấy từ ảnh chụp màn hình WinDbg, có 2,5 Gb sử dụng bộ nhớ chưa được phân loại và hầu hết trong số đó là 2,1 Gb thực sự là bộ nhớ dành riêng (MEM_RESERVE). Tôi có kinh nghiệm gỡ lỗi bãi rác, nhưng kịch bản này là một cái gì đó mới với tôi. MEM_COMMIT là bỏ thuốc lá OK - 564,270 Mb, quản lý kích thước heap là abt 82 Mb

enter image description here

Tôi cũng kiểm tra đống bản địa để xem, nếu có khối lớn của dữ liệu được bảo tồn, nhưng không thể tìm thấy bất cứ điều gì đáng ngờ có một trong hai

enter image description here

Vì vậy, câu hỏi của tôi là - là nó có thể rằng MEM_RESERVED có thể dẫn đến oom ngoại lệ? Nếu vậy, làm thế nào tôi có thể gỡ lỗi nó, xem lý do tại sao/làm thế nào số lượng lớn bộ nhớ đang được dành riêng? Bạn sẽ tìm nơi nào khác để tìm ra vấn đề có thể là gì?

Nếu có bất kỳ thông tin nào khác được yêu cầu, vui lòng yêu cầu và tôi sẽ cập nhật bài đăng của mình.

Trả lời

6

Có, việc đặt trước bộ nhớ có thể kích hoạt OutOfMemoryException. Hãy thử phân bổ một vài mảng byte rất lớn. Bộ nhớ cho những điều này sẽ không được cam kết cho đến khi bạn ghi vào nội dung của các mảng. Tuy nhiên, bạn có thể dễ dàng kích hoạt OOM chỉ bằng cách phân bổ các mảng này.

Tôi không biết chi tiết triển khai, nhưng vì VirtualAlloc sẽ không thành công nếu không thể tôn trọng yêu cầu dự trữ, tôi giả định CLR dịch điều này thành ngoại lệ. Tôi không thấy làm thế nào nó có thể biến một yêu cầu dự trữ thất bại thành bất cứ điều gì hữu ích, do đó, một ngoại lệ là một sự lựa chọn hợp lý.

+0

cảm ơn bạn đã trả lời, bạn có biết bất kỳ cơ hội nào để tôi có thể xem những gì có thể lưu trữ bộ nhớ khổng lồ này trong WinDbg không? – Michael

+0

Giả sử bộ nhớ được sử dụng bởi đối tượng được quản lý, bạn có thể kiểm tra chúng bằng cách sử dụng '! Dumpheap' và'! Do'. Tuy nhiên, với điều kiện đầu ra của '! Eeheap' chỉ ra rằng vùng được quản lý là nhỏ, tôi giả định rằng một cái gì đó khác đã dành riêng bộ nhớ này. –

+0

Bạn có thể chỉ định những gì người khác có thể đặt trước bộ nhớ không? Tôi bối rối vì tôi mong rằng "cái gì đó" hoặc là trên đống được quản lý, hoặc một số tài nguyên gốc trên đống bản địa - không phải trong số chúng trỏ đến bất kỳ điều đáng ngờ nào. Điều gì khác có thể dự trữ bộ nhớ? Tôi sẽ vui mừng hơn khi kiểm tra nó ngay lập tức. – Michael

3

OutOfMemoryException xảy ra nếu hệ thống không thể cấp phát thêm bộ nhớ ảo cho ứng dụng của bạn. Bộ nhớ dự trữ là bộ nhớ ảo và do đó chiếm các giới hạn đó.

Bạn có thể thử mà trong C++ một cách dễ dàng nhất:

while(::VirtualAlloc(NULL, 65536, MEM_RESERVE, PAGE_READWRITE) != NULL); 
std::cout << "All memory reserved. Now check with tools." << std::endl; 

Nếu VirtualAlloc() trả về NULL, nó không thể phân bổ memoy hơn. Trong WinDbg này sẽ hiển thị

MEM_RESERVE 32307 7f6f2000 (1.991 Gb) 99.59% 99.56% 

Tuy nhiên, VirtualAlloc() không cấp phát bộ nhớ trên heap, vì vậy !heap là không hữu ích trong trường hợp này và chỉ hiển thị các quá trình mặc định đống:

0:000> !heap 
Index Address Name  Debugging options enabled 
    1: 00440000 

Đó là cách khác vòng: heap mamanger sử dụng VirtualAlloc() để có được bộ nhớ. Cũng lưu ý rằng .NET cũng không sử dụng trình quản lý heap. Nó cũng cấp phát bộ nhớ trực tiếp bằng VirtualAlloc() và sau đó tự quản lý nó. Vì vậy, bởi vì bạn có thể nhìn thấy nó trong đầu ra của !heap nó không phải là một vấn đề .NET, nó là một vấn đề bộ nhớ riêng.

Trong sự hiểu biết ngây thơ của tôi, thiết lập gflagsEnable heap tagging by DLL phải hữu ích để xác định nguồn của phân bổ vùng heap. Tuy nhiên, kỳ vọng của tôi rằng lệnh !heap -t chỉ đơn giản là hiển thị tên của DLL được cấp phát bộ nhớ đã không thành hiện thực.

+0

cảm ơn bạn đã nhập. Tôi đã thử lệnh heap -t, nhưng nó không có ích gì cả. Tôi đang cố gắng đào sâu vào bộ nhớ riêng để xem những gì tôi có thể tìm thấy ở đó. Bất kỳ đề xuất khác để kiểm tra cái gì khác rất hoan nghênh. – Michael

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