2009-02-03 7 views
3

C# 및 asp.net을 사용하는 웹 응용 프로그램에서 작업 중입니다. 메모리 부족 예외가 발생했습니다. 응용 프로그램에서 데이터 원본에서 많은 레코드 (제품)를 읽거나 수백/수천 개가 될 수 있으며 마법사의 설정을 통해 해당 레코드를 처리 한 다음 프로세스 제품 정보로 다른 데이터 원본을 업데이트합니다. 여러 DB 클래스가 있지만 현재 모든 논리는 하나의 큰 클래스에 있습니다. 이것에 대한 유일한 이유는 모든 정보가 한 가지, 제품과 관련이 있다는 것입니다. 내 응용 프로그램을 다른 클래스로 나누면 메모리가 도움이 될까요 ?? 비즈니스 로직을 두 클래스로 나눈다면 두 클래스 모두 서로에게 메시지를 보내는 동안 살아 남을 것이고 이것이 어떻게 도움이 될지 모르겠다. 내 다른 해결책은 모든 기억을 빨아들이는 것을 발견하는 것일 것입니다. 당신이 추천 할 수있는 좋은 도구가 있습니까 ??메모리 부족 예외

감사합니다.

답변

10

데이터 리디렉션을 사용하여 데이터를 스트리밍하고 있습니까?

나는이 문제를 해결하기 위해 사소한 문제라고 말하며, 1 백만 개의 레코드로 데이터 테이블을 펌핑하거나, 한 번에 한 테이블 씩 작업하거나, 작은 배치로 작업하지 않습니다. .. 당신이 그것으로 끝나면 물건을 풀어 놓아라. (예 : static List<Customer> allCustomers = AllCustomers()을 가지고 있지 않음)
X 개 이상의 행이 포함되어 있으면 아무도 메모리로 테이블을 읽지 않도록하는 개발 룰이 있습니다.

.net memory profiler 또는 windbg with the sos extension에서이 모양을 디버깅하는 도구가 필요한 경우 모두 관리 힙을 스니핑 할 수 있습니다.

유지 보수가 중요하고 결함 수를 줄이려면 SuperDuperDoEverything 클래스를 제거하고 도메인과 더 잘 일치하는 방식으로 정보를 모델링하십시오. SuperDuperDoEverything 클래스는 폭파를 기다리는 폭탄입니다.

1

시작하기 Perfmon; GC 관련 정보에는 여러 가지 카운터가 있습니다. 메모리 누수 가능성이 높습니다 (그렇지 않으면 GC가 객체를 삭제할 것입니다). 더 이상 필요하지 않은 데이터 구조를 계속 참조하고 있음을 의미합니다.

1

당신은 여러 개의 클래스로 분할해야합니다.

DB 연결을 닫으시겠습니까? 파일을 읽는 경우 읽기/쓰기가 끝나면 닫거나 해제합니까? 다른 객체에도 동일하게 적용됩니다.

메모리를 해제하기 위해 클래스 객체를 주기적으로 순환시킬 수 있습니다.

6

은 또한 당신이 실제로 실행되지 않을 수 있습니다, 릴리스는

  • 가까운 연결

  • 당신은 항상이 시도 할 수 개체를

    • , 그것을 정리해 메모리가 부족합니다. 그것은 일어난 일입니다.NET은 연속적인 메모리 블록을 찾기 위해 이동하고 아무 것도 찾지 못하면 요청을 처리 할 총 메모리가 충분하더라도 OOM을 throw합니다.

      누군가가 Perfmon 및 WinDBG를 참조했습니다. 또한 충돌시 메모리 덤프를 캡처하도록 adplus를 설정할 수도 있습니다. 구문이 adplus -crash -iis이라고 생각합니다. 메모리 덤프가 있으면 다음과 같이 할 수 있습니다.

      .symfix C:\symbols 
      .reload 
      .loadby sos mscorwks 
      !dumpheap -stat 
      

      그러면 메모리 사용량이 많은 객체에 대한 아이디어를 얻을 수 있습니다.

      물론 Tess Fernandez's 우수 블로그를 확인하십시오. 예를 들어이 문서의 내용은 Memory Leaks with XML Serializers이며 문제를 해결하는 방법은 다음과 같습니다.

      dev 환경에서 이것을 repro 할 수 있고 개발자 용 VS Team Edition이있는 경우 메모리 프로파일 러가 내장되어 있습니다. 새로운 성능 세션을 시작하고 앱을 실행하기 만하면됩니다. 그것은 주변에 매달려있는 것에 대한 좋은 보고서를 뱉어 낼 것입니다.

      마지막으로 개체가 소멸자를 정의하지 않았는지 확인하십시오. 이것은 C++가 아니며, finalizer 큐에 놓여 야하고 다음 라운드를 정리해야하기 때문에 객체가 가비지 컬렉션 라운드에서 생존 할 수 있다는 것을 보장하는 것 외에는 결정적인 것은 없습니다.

    3

    문제점을 발견했습니다. 내 루프를하는 동안 나는 지워지지 않는 콜렉션을 가지고 있었고 그래서 데이터는 계속 추가되었다.