2012-07-17 3 views
0

XP 시스템에서 실행하는 데 사용되는 C# 응용 프로그램이 있습니다. 최근에 Windows 7.0 시스템으로 전환했습니다. "System.StackOverflowException"디버거에있는 경우XP 시스템에서 7.0 시스템으로의 System.StackOverflowException

나는 다음과 같은 오류 메시지가 있습니다. 아직도 XP 기계를 가지고 있고,이 기계에 문제가 없다.

재귀 알고리즘 중간에 오버플로가 발생합니다. 이 문제에 익숙한 사람이라면 누구입니까? 그것은 이것과 관련이있는 운영체제입니까 아니면 머신 자체입니까? 당신의 도움에 대한

많은 감사,

마이클

+9

일부 코드를 게시 할 수 있습니까? 그것이 무엇인지를 아는 데 도움이 될 수 있습니다. – NominSim

+2

하드웨어 사양을 알려 주실 수 있습니까? RAM이 가장 중요합니다. –

+2

@ AlvinWong 하드웨어 문제라고 생각하지 않습니다. 스택 공간이 부족하면 프로세스가 해당 스레드 스택에 할당 된 1MB를 사용했음을 의미합니다. –

답변

0

재귀 어떻게 재귀?

무엇이든 deeper than about ten or so could be risky.

당신은 스택을 소모하는 경우 그리고 당신은, 당신이 당신의 자신의 스택을 관리 할 수있는 버그가 아니다 확신 ... 예를 들어

:

void Process(SomeType foo) 
{ 
    DoWork(foo); //work on foo 
    foreach(var child in foo.Children) 
    { 
     Process(child); 
    } 
} 

void Process(SomeType foo) 
{ 
    Stack<SomeType> bar=new Stack<SomeType>(); 
    bar.Push(foo); 
    while(bar.Any()) 
    { 
     var item=bar.Pop(); 
     DoWork(item);//work on item 
     foreach(var child in item.Children) 
     { 
      bar.Push(child); 
     } 
    } 
} 
될 수 있습니다

따라서 모든 CLR 호출 스택 문제를 제거합니다.

물론 이것은 무제한 재귀를 수정하지 않습니다.

0

나는하지이 당신의 PC의 물리적 RAM과 아무 상관 가지고 있다고 생각하지 . 나는 XP에서 볼 수 없었던 이유가 Windows 7이 .Net의 다른 버전을 가지고있을 뿐이라고 의심합니다.

분명히, 당신은 어떻게 든 재귀의 깊이를 제한 (또는 비 재귀 루프를 대체 할) 필요가있다.

하지만 당신은 잠재적 닷넷 스택 (들)을 구성 할 수 있습니다. 이 링크를보고하십시오 :

1

재귀가 도달하기 전에 XP에 간다 얼마나 깊이 알고 도움이 될 것입니다 기본 케이스, Win7에서 오류가있는 곳.

이론적으로, 윈도우 7 프로세스는 WINXP 과정보다 더 많은 사용 가능한 스택 공간이 있어야합니다; 최소한 그들은 동일해야합니다. 그러나 여기에는 다른 요인들이 있습니다. 이 블로그 게시물 체크 아웃 : 한마디로 http://blogs.technet.com/b/markrussinovich/archive/2009/07/08/3261309.aspx

을 제한 요인은 "상주 사용 가능한 메모리"보통; 이것은 거기에 보관해야하며 페이지 파일로 스왑 할 수없는 데이터에 사용할 수있는 실제 RAM (페이지 파일 공간 아님)입니다.많은 것들이 일반 컴퓨터에 "상주"로 보관되어야하며 페이지 파일로 스왑 될 수 없습니다. 가장 중요한 것은 "커널 모드"(코어 시스템에 직접 액세스해야 함)에서 실행되어야하는 모든 것이 해당 프로세스에 대한 활성 스레드가없는 경우에도 페이지 폴트를 방지하기 위해 RAM에 유지되어야한다는 것입니다.

Windows 7에는 이러한 "커널 모드"프로세스가 더 많이 있습니다. 예를 들어 WinXP에 포함되지 않은 Windows Aero는 그래픽 카드를 사용하여 바탕 화면 렌더링을 가속화하므로 커널 모드로 실행해야합니다. Windows 7 커널 자체는 더 큰데, 그 이유는 추가 보안 및 내장 된 하드웨어 지원이 추가되기 때문입니다. Windows 7에는 WinXP에없는 커널 모드에서 실행되는 추가 백그라운드 프로세스 등이 있습니다.

다른 모든 것들이 동일하면 (RAM 포함), Windows 7 컴퓨터는 재귀 알고리즘에 커밋 할 수있는 상주 메모리가 실제로 적습니다. 즉 알고리즘이 기본에 도달 할 정도로 충분히 반복적으로 재귀 할 수 없음을 의미합니다 새 호출에 필요한 "커밋"을 충족시킬 수있는 충분한 상주 메모리가 Windows에 없기 때문에 호출 전에 StackOverflowException이 트리거됩니다.

또한 Windows 7은 메모리에있는 것들을 다르게 정렬합니다. 오래된 Windows 버전 (XP 및 이전 버전)은 각 새 프로세스에 대한 메모리 공간을 대략 순차 방식으로 예약했습니다. N + 1 번째 프로세스 (또는 쓰레드)는 N 번째 프로세스/쓰레드를 위해 예약 된 마지막 블록 다음의 1 블록 뒤에 메모리 주소가 주어진다. Windows Vista부터는 메모리가 "임의"방식으로 할당되었습니다. Windows는 다른 예약 된 블록에 인접하거나 그렇지 않을 수도있는 메모리의 위치를 ​​선택합니다 (다른 예약 된 블록의 일부가 아닌 것으로 보장됩니다). 이것은 맬웨어를 혼동하고 다른 프로세스의 메모리에서 스누핑하는 것을 방지하기 위해 고안된 보안 기능입니다. 그러나 공간 효율적인 할당 방식이 적 으면 OS가 각 새 스레드에 할당하기 위해 연속 RAM의 1MB 블록을 더 빨리 소모하게됩니다. 그 시점에서 갭을 할당하기 시작합니다. 따라서 Windows 7 시스템의 특정 메모리 사용 공간에 따라 재귀 함수의 스레드가 보통 1MB의 스택 공간을 요청할 수 있으며 실제 128K의 연속 공간 만있는 OS에 의해 포인터가 제공 될 수 있습니다. 프로그램이 예약했다고 생각한 모든 공간을 실제로 커밋 할 수 없을 때까지는 프로그램에서 차이점을 알 수 없습니다. 이것은 Heisenbugs를 생성 할 수 있지만, 한 번만 작동하지만 매번 스레드가 예약하는 정확한 메모리 공간의 비 결정적 차이로 인해 다음 번에 실패합니다.

이 모든 답변은 "more RAM"입니다. 핵심 커널 모드 프로세스에 필요한 양은 비교적 정적이므로 추가 할 수있는 추가 RAM 1GB는 사용자 프로그램 프로세스 및 스레드에서만 사용할 수있는 GB입니다.

관련 문제