Tôi có một ứng dụng trải nghiệm sự rò rỉ bộ nhớ chậm từ từ đi.Làm cách nào tôi có thể tìm thấy lý do cho hàng đợi của trình hoàn tất treo?
Sử dụng ANTS Memory Profiler Tôi có thể thấy rằng tất cả bộ nhớ bị rò rỉ đang được giữ bởi gốc GC của trình kết thúc hàng đợi.
Tôi nghi ngờ những gì có thể đã xảy ra là trình hoàn thành bị bế tắc trên khóa để có sẵn.
Không có lớp nào của chúng tôi triển khai các trình kết thúc rõ ràng, chúng tôi tránh chúng như quy tắc, điều này khiến tôi nghĩ khóa có thể liên quan đến hệ thống hoặc lớp thư viện.
Tôi đã sử dụng SOS.dll
để có một cái nhìn tại các nội dung của hàng đợi finalizer và nếu tôi giải thích một cách chính xác thì nó báo cáo mục đầu tiên là một ví dụ System.Threading.Thread
Tuy nhiên tôi không chắc chắn nếu người đứng đầu của hàng đợi thực sự đại diện đối tượng đang được xử lý hoặc đối tượng tiếp theo sẽ được xử lý.
- Có bất kỳ thủ thuật nào tôi có thể sử dụng để tìm hiểu những gì đang được hoàn thành không?
- Có cách nào tôi có thể tìm hiểu xem khóa của trình hoàn thiện đang chờ gì?
- Có thể bật thêm bất kỳ lỗi nào để theo dõi hành động của chuỗi kết thúc không?
- Tôi có thể xem xét điều gì khác?
Cập nhật
đống Các chủ đề finalizer xuất hiện như sau:
[email protected]() + 0x15 bytes
[email protected]() + 0x15 bytes
[email protected]() + 0x15 bytes
[email protected]() + 0x43 bytes
[email protected]() + 0x12 bytes
ole32.dll!GetToSTA() + 0x72 bytes
ole32.dll!CRpcChannelBuffer::SwitchAptAndDispatchCall() - 0x1939 bytes
ole32.dll!CRpcChannelBuffer::SendReceive2() + 0xa6 bytes
ole32.dll!CAptRpcChnl::SendReceive() + 0x5b7 bytes
ole32.dll!CCtxComChnl::SendReceive() - 0x14b97 bytes
ole32.dll!NdrExtpProxySendReceive() + 0x43 bytes
[email protected]@4() + 0xe bytes
rpcrt4.dll!_NdrClientCall2() + 0x144 bytes
[email protected]() + 0x7a bytes
[email protected]() + 0xf bytes
ole32.dll!CObjectContext::InternalContextCallback() - 0x511f bytes
ole32.dll!CObjectContext::ContextCallback() + 0x8f bytes
clr.dll!CtxEntry::EnterContext() + 0x119 bytes
clr.dll!RCWCleanupList::ReleaseRCWListInCorrectCtx() + 0x2bb bytes
clr.dll!RCWCleanupList::CleanupAllWrappers() - 0x20fb0 bytes
clr.dll!SyncBlockCache::CleanupSyncBlocks() + 0x1ec6 bytes
clr.dll!Thread::DoExtraWorkForFinalizer() + 0x411b5 bytes
clr.dll!WKS::GCHeap::FinalizerThreadWorker() + 0x8b bytes
clr.dll!Thread::DoExtraWorkForFinalizer() + 0xb6e76 bytes
clr.dll!Thread::ShouldChangeAbortToUnload() - 0x5f8 bytes
clr.dll!Thread::ShouldChangeAbortToUnload() - 0x53d bytes
clr.dll!ManagedThreadBase_NoADTransition() + 0x35 bytes
clr.dll!ManagedThreadBase::FinalizerBase() + 0xf bytes
clr.dll!WKS::GCHeap::FinalizerThreadStart() + 0xfb bytes
clr.dll!Thread::intermediateThreadProc() + 0x48 bytes
[email protected]@12() + 0x12 bytes
[email protected]() + 0x27 bytes
[email protected]() + 0x1b bytes
Tại sao bạn tránh trình hoàn thành dưới dạng quy tắc? Thực hiện đúng mô hình dùng một lần * yêu cầu * finalizer. – svick
@svick - Một lưu ý về MSDN lại. triển khai IDisposable nói "Bỏ qua finalizer hoàn toàn nếu một lớp không sở hữu tài nguyên không được quản lý" – chillitom
@svick - chillitom là chính xác. Trích dẫn [Nguyên tắc thiết kế khung] (http://www.amazon.com/Framework-Design-Guidelines-Conventions-Libraries/dp/0321545613): "Bạn thực sự không muốn viết một finalizer nếu bạn có thể giúp nó." – TrueWill