최근에 WinForms 앱에서 .NET "메모리 누수"(예기치 않은 느린 GC 루팅 된 객체)를 조사했습니다. 거대한 보고서를로드하고 닫은 후에도 gen2 모음을 몇 개 사용한 후에도 메모리 사용량이 예상대로 감소하지 않았습니다. 누락 된 이벤트 처리기로보고 컨트롤을 유지한다고 가정 할 때 열린 WinDbg를 열어서 어떤 일이 발생했는지 알 수있었습니다..NET RegEx "메모리 누수"조사
!dumpheap -stat
명령은 문자열 인스턴스에서 많은 양의 메모리를 사용한다고보고했습니다. 더 나아가 이것을 !dumpheap -type System.String
명령으로 수정하면 보고서에 사용 된 90MB 문자열 인 주소 03be7930이 발견되었습니다. 마지막 단계는 !gcroot 03be7930
을 호출하여 어떤 객체가 활성 상태로 유지되는지 확인하는 것입니다.
내 기대치가 잘못되었습니다.보고 컨트롤 (및 보고서 문자열)에 걸려있는 unhooked 이벤트 처리기가 아니었지만 대신 System.Text.RegularExpressions.CachedCodeEntry
의 자손 인 System.Text.RegularExpressions.RegexInterpreter
인스턴스가 보유하고있었습니다. 지금, Regex의 캐싱은 (다소) 일반적인 지식으로 Regex를 사용할 때마다 재 컴파일해야하는 오버 헤드를 줄이는 데 도움이됩니다. 그러나 이것이 내 문자열을 살아있게 유지하는 것과 무슨 상관이 있습니까?
Reflector를 사용하여 분석 한 결과 Regex 메서드가 호출 될 때마다 입력 문자열이 RegexInterpreter에 저장되는 것으로 나타났습니다. RegexInterpreter는 후속 Regex 메서드 호출을 통해 새 문자열이 입력 될 때까지이 문자열 참조를 유지합니다. Regex.Match 인스턴스 및 다른 인스턴스에 매달아 비슷한 동작을 기대합니다.
- Regex.Split, Regex.Match, Regex.Replace 등
- Regex.Run
- RegexScanner.Scan (RegexScanner는 기본 클래스, RegexInterpreter : 체인이 같은 것입니다 위에서 설명한 서브 클래스입니다).
정규식은보고를 위해 사용되는 잘못된
- Regex.Run
모두 나는이 시나리오를 해결하는 방법 또는 최소한이 시나리오를 해결하는 방법에 대한 몇 가지 옵션을 발견했습니다. 나는 지역 사회가 먼저 반응하도록 할 것이고, 아무도 찾는 사람이 앞으로 나오지 않으면 나는 하루나 이틀 안에 어떤 격차라도 메울 것이다.
Regex를 만들 때'Compiled' 옵션을 사용하고 있습니까? –
아니요,이 경우 '컴파일 된'옵션이 사용되지 않았습니다. –