며칠 및 몇 달 동안 다시 시작하지 않고 실행해야하는 Windows 콘솔 앱이 있습니다. 응용 프로그램은 MSMQ에서 "작업"을 검색하고 처리합니다. 작업 청크를 동시에 처리하는 스레드가 30 개 있습니다.대기열에서 오는 대형 객체 힙 및 문자열 객체
MSMQ에서 오는 각 작업 청크는 약 200kb이며 대부분은 단일 String 개체에 할당됩니다.
약 3 ~ 4,000 개의 이러한 작업 청크를 처리 한 후 응용 프로그램의 메모리 소비가 엄청나게 많은데 1 ~ 1.5GB의 메모리를 소비한다는 사실을 알게되었습니다.
프로필러를 통해 앱을 실행하고 대형 메모리 힙에서이 메모리 (대부분 작살 등)가 사용되지 않지만 구조가 조각났다는 사실을 알게되었습니다.
이러한 사용되지 않은 (가비지 수집 된) 바이트 중 90 %가 이전에 할당 된 문자열임을 알게되었습니다. MSMQ에서 들어오는 문자열이 할당되고 사용 된 다음 할당이 해제되어 조각화의 원인이되었다고 의심하기 시작했습니다.
GC.Collect (2 또는 GC.Max ...)와 같은 것은 대형 오브젝트 힙을 gc하지만 압축하지 않았기 때문에 도움이되지 않는다는 것을 이해합니다 (여기서 문제가 됨). 그래서 내가 필요로하는 것은 이러한 문자열을 캐싱하고 어떻게 든 다시 사용할 수 있다고 생각하지만 String은 불변이므로 StringBuilders를 사용해야합니다.
내 질문입니다. 기본 구조를 변경하지 않아도됩니까 (예 : MSMQ를 사용하여 변경할 수 없으므로) LOH를 조각 내기 위해 항상 매번 새 문자열을 초기화하지 마십시오.
감사합니다, 야 니스
UPDATE :이 "작업"덩어리가 현재 현재
을 검색하는 방법이가 MSMQ에서 WorkChunk 개체로 저장되는 정보. 이러한 각 객체는 Contents라는 문자열과 Headers라는 다른 String을 포함합니다. 이것은 실제 텍스트 데이터입니다. 필요하다면 스토리지 구조를 다른 것으로 변경하고 MSMQ가 아닌 다른 스토리지 메커니즘을 잠재적으로 변경할 수 있습니다. 작업자 노드 측면에서
현재 우리가 할
WorkChunk 덩어리 = _Queue.Receive();
따라서이 단계에서 캐시 할 수있는 정보가 거의 없습니다. 만약 우리가 구조를 어떻게 든 변경했다면 우리는 약간의 진전을 이룰 수 있다고 생각합니다. 어쨌든 우리는이 문제를 해결해야한다. 그래서 우리는 몇 달 간의 일을 포기하지 않기 위해 필요한 모든 것을 할 것이다.
업데이트 : 아래 제안 사항 중 일부를 시도해 본 결과 로컬 컴퓨터 (Windows 7 x64 및 64 비트 앱 실행)에서이 문제를 재현 할 수 없음을 알게되었습니다. 이것은 일을 훨씬 더 어렵게 만듭니다. 왜 누군가가 왜이 문제를 현지에서 재발견하는 데 정말로 도움이되는지 알고 있다면.
어떻게 이러한 문자열을 수신합니까? 일단 문자열이되면 붙어 있습니다. 나는 그들이 스트림이나 바이트 []에서 왔어 몇 가지 옵션이있을 수 있습니다. –
안녕하세요 Henk -이 작업 청크에 대한 자세한 정보를 얻으려는 업데이트를 확인하십시오 – Yannis
하지만 실제 문제입니까? > = 8GB RAM을 갖춘 64 비트 PC에서 1.5GB를 계속 사용할 수 있어야합니다. –