2011-06-13 4 views
3

콘솔 응용 프로그램에서 호스팅되는 WCF 서비스가 있습니다. WCF의 운영 계약서를 호출하려면 ChannelFactory이 있어야합니다.WCF 직렬화 및 캐싱

문제 : 값을 반환하는 연산을 호출 할 때마다 반환 된 값은 직렬화 될 때 서비스에 의해 캐시됩니다.

Windows 7에서 작업 관리자를 통해 서비스 메모리 사용량을 확인하고 있습니다. 아무 것도 반환하지 않는 작업을 호출하면 메모리가 증가하지 않지만 데이터를 반환하는 작업을 호출하면 메모리가 증가하고이 상태를 유지합니다 데이터가 클라이언트에 반환 된 후에도

제 생각에 이것이 직렬화 캐싱 문제입니까?

+1

일부 메모리 프로파일 링을 실행하고 어떤 객체가 메모리에 남아 있는지 확인하십시오. 명시 적 캐싱 또는 정적 변수를 사용하여 데이터를 보유합니까? – oleksii

답변

2

GC가 실행될 때까지 메모리가 증가 할 가능성이 있으며 데이터가 클라이언트에 반환되는 시점과 일치하지 않습니다.

중단 점을 추가하거나 서비스 메서드에 일종의 로깅을 시도하여 각 요청에서 메서드가 호출되고 있는지 확인 했습니까? WCF가 자체적으로 캐싱을 수행한다고 생각하지 않습니다. 적어도, 나는 그것을 사용하는 나의 응용 프로그램에서 그것을 한 적이 없어.


편집 :

메모리는 가비지 컬렉터가 실행 될 때까지 사용을 유지합니다. 프로세스가 여전히 힙에 여유 공간이 충분하다면 GC가 실행될 이유가 없습니다. MSDN에 따르면

: 다음 중 하나의 조건에 해당하는 경우 http://msdn.microsoft.com/en-us/library/ee787088.aspx#conditions_for_a_garbage_collection

가비지 콜렉션 발생

  • 시스템은 낮은 물리 메모리를 갖는다.

  • 관리되는 힙의 할당 된 개체가 사용하는 메모리가 은 허용 가능한 임계 값을 초과합니다. 이것은 허용되는 메모리 사용량이 인 임계 값이 관리 힙에서 을 초과했음을 의미합니다. 이 임계 값은 프로세스가 실행될 때 으로 계속 조정됩니다.

  • GC.Collect 메서드가 호출됩니다. 거의 모든 경우에 가비지 수집기가 연속적으로 실행되기 때문에 이 메서드를 호출 할 필요가 없습니다. 이 방법은 주로 고유 한 상황 및 테스트에 사용됩니다.

당신이 힙에 객체를 할당하는 가능성이 있지만, GC는 더 힙 세대의 열린 공간은 여전히 ​​존재 (실행하는 이유를 볼 수없고, 때문에 그들은 GC'd되는되지 않습니다 그것을 지우는 시간을 보내는 이유).

그러나 WCF 호출을 계속 반복하여 결국 메모리 부족 예외가 발생하면 실제로 참조가 어딘가에 보관되는 데 문제가 있음을 나타냅니다. 이 경우, 메모리 프로파일 러를 사용하여 무엇이 보유되고 있는지, 무엇에 의해 유지되는지를 결정합니다.


편집 # 2 :

또한보십시오이 스레드 : C# Thread not releasing memory

+0

네, 당신이 언급 한 것을했습니다. 메소드는 각 요청에서 호출됩니다. 그리고 기억이 증가하고 결코 자유 로워 질 때마다! – scatman

+0

오, 오케이, 아마도 나는 당신의 질문을 잘못 읽었을 것입니다. 나는 당신이 응답이 캐시되고 메소드가 다시 실행되지 않는 것처럼 동일한 응답이 클라이언트에게 계속해서 보내지는 것을 의미한다고 생각했습니다. 내 대답을 편집 할 것입니다 ... – CodingWithSpike

+0

개체가 아직 사용 중이므로 작업에서 컬렉션을 호출 할 수 없습니다. –

3

가비지 수집기가 아직 실행되지 않은 것처럼 들리며 메모리가 해제되지 않았기 때문에 소리가납니다. 또한 콘솔 응용 프로그램에서 WCF 서비스를 호스팅 할 때는 GC이 워크 스테이션 모드로 실행되므로이 ​​경우 효과가 떨어질 수 있습니다.

+0

GC 실행 시간은 언제입니까? 스택 오버플로 예외가 있고 여전히 GC가 실행되지 않았습니다. 어쨌든 수동으로 메모리를 비울 수 있습니까? 아니면 GC를 호출할까요? – scatman

+1

@scatman - StackOverflow 예외가있는 경우 완전히 다른 문제가 발생합니다. 보통 어떤 종류의 재귀가 완료되지 않았 음을 나타냅니다. public void MethodA() {MethodB(); } public void MethodB() {MethodA(); }'이 함수 중 하나를 호출하면 무한 루프가 발생하고 호출 스택이 너무 깊어 질 때마다 최종 StackOverflowException이 발생합니다. – CodingWithSpike

+0

@scatman - 여기에 언급 된대로'System.GC.Collect()'를 호출하여 수동으로 GC에 실행을 지시 할 수 있습니다. http://msdn.microsoft.com/en-us/library/system.gc.collect.aspx 그러나 그 가능성이 귀하의 StackOverflowException 도움이되지 않습니다. 개체 참조가 가비지 수집을 방지하는지 확인하는 데 도움이 될 수 있습니다. – CodingWithSpike

1

수집/생성되고 어떤 객체를 참조하기 위해이 같은 도구를 사용하여 http://memprofiler.com/

나는 않을 것 GC가 각 호출 후에 실행되지 않으면 걱정할 필요가 없습니다. 어쨌든 매우 효율적이지는 않습니다. 가비지 수집기는 .NET 프레임 워크가 객체를 충분히 수집하여 수집 할 수 있다고 판단한 시점에 실행됩니다. 메모리가 부족한 상태로 실행되면 더 자주 발생합니다.