2012-07-02 3 views
3

가상 크기가 약 2GB (32 비트 응용 프로그램, 큰 주소 인식 가능) 인 경우 Windows에서 C++을 사용하여 빌드 한 서버 응용 프로그램에서 메모리가 부족합니다. 그러나 Private Bytes는 상당히 작습니다. 현재 통계는 다음과 같습니다가상 크기로 인해 프로그램이 메모리를 소모합니다.

가상 크기 : 전용 바이트 2.6GB : 1.6GB

이 두 숫자의 차이가 1기가바이트입니다. 따라서 내 질문은 다음과 같습니다.

  1. 1GB 차이는 무엇을 나타 냅니까?
  2. 가상 크기 또는 비공개 바이트 때문에 응용 프로그램이 메모리가 부족합니까?

또한 VMMap 유틸리티를 통해 응용 프로그램을 실행했으며 "개인 데이터"는 일반적으로 커밋 된 크기보다 큰 순서입니다. 즉, 개인 데이터의 총 크기는 200MB 일 수 있지만 커미트 된 크기는 20MB에 불과합니다. 나는 개인 데이터가 무엇인지는 잘 모르지만, 지금까지의 연구를 토대로 볼 때 그것은 단지 힙의 일부라는 것을 나타내는 것으로 보인다.

편집 :

내가 퓨리를 사용하여 메모리 누수를 찾았다 적이 있지만 정말 유용한 아무것도 발견되지했습니다. 포인터가없는 메모리 형태의 메모리 누수는 문제가되지 않지만 메모리 누수가 너무 길면 메모리 누수가 문제가 될 수 있습니다. 아직 보지 못했습니다. 그러나 핵심은 왜 가상 크기가 메모리 부족 문제를 일으키는 지 이해하는 것입니다. 질문 1이 나를 이해하는 데 가장 중요합니다. 전용 바이트 대

+0

아마도 수정해야 할 메모리 누수가 하나 이상 있습니까? –

+0

Committed = 응용 프로그램에서 실제로 사용중인 메모리, private = 응용 프로그램 용으로 특별히 예약 된 메모리? 가상 크기 = 디스크에 페이징 된 데이터의 양입니다. 나는 확실히 그것에 대해 알아야 할 것입니다. – JAB

+0

@JAB 잘못되었습니다. 나는 대답을 게시 할 것이다. – Polynomial

답변

6

이것은 약간의 설명이 필요하므로 여기에 나와 함께하십시오.

먼저이 항목은 혼란스러운 용어의 혼란입니다. 따라서 "가상 메모리"가 디스크와 관련된 모든 개념을 버리십시오.

  • 물리적 메모리 물리적 장치에 저장된 메모리이다. 일반적이
  • 가상 메모리가 사용자 모드에 매핑 된 물리 어드레스 범위의 세트이다 은 (가상) 어드레스 너무 범위 디스크 완충제, NIC 버퍼 그래픽 카드 VRAM 등 시스템 RAM을 지칭하지만,도 될 수있다 그 메모리는 안전하고 구획화 된 방식으로 액세스 될 수 있습니다.

빠른 노트는 왜 우리가 이렇게 : 우리가 직접 메모리 주소 프로세스를 준 경우, 우리는 (실행 가능하게) 단일 메모리 저장소를 가질 수있다. 이것은 성능면에서 불편하고 좋지 않습니다. 가상 주소가 시스템 메모리 (RAM) 범위를 벗어나는 실제 주소로 변환되면 프로세서는 페이지 오류를 발생시킵니다. 이것은 OS의 인터럽트 처리기에 신호를 보내면 OS는 메모리 액세스 작업을 다른 장치에 위임 할 수 있습니다. 유능한!

32 비트 Windows 시스템에서 어떤 특정 시점에에서 프로세스가 을 처리 할 수있는 가상 메모리의 최대 크기는 2GB입니다. AWE를 사용하면 3GB, /4GT 및 AWE를 사용하면 4GB로 늘릴 수 있습니다. 이것은 프로세스가 메모리의 2GB (또는 앞에서 설명한 설정에 따라 3GB/4GB) 만 할당 할 수 있음을 의미하지 않습니다. 단지 그 이상의 동시 액세스를 가질 수 없음을 의미합니다.

예를 들어 크기가 1GB 인 메모리 매핑 파일을 열면 가상 메모리 사용이 1GB 증가합니다. RAM이나 디스크를 건드리지는 않지만 프로세스에 가상 주소 공간 블록을 할당했습니다. 이 메모리 맵핑 된 파일을 사용할 수있는 것과 동시에 1.1GB의 RAM을 할당하려는 경우에는 그렇게 할 수 없습니다. 먼저 프로세스에서 파일의 맵핑을 해제해야합니다. 메모리는 할당 된 상태로 유지되고 데이터로 가득 차 있지만 실제로 프로세스에 매핑되지는 않습니다. 컴퓨터에 8GB RAM이있는 경우 6GB를 데이터로 채우고 2GB를 해당 프로세스에 매핑 할 수 있습니다. 해당 메모리의 다른 섹션을 사용해야하는 경우 기존 블록을 매핑 해제하고 다른 섹션을 매핑해야합니다.

그래서, 그 차이에 당신이보고있는 :

  1. 개인 바이트를 알려줍니다 다른 프로세스와 공유 가상 메모리 제외 프로세스가 매핑 한 가상 장치 메모리의 바이트 수 (예를 들어 파일을 매핑하는 방법, 글로벌 힙, 등).

  2. 실제 작업 세트는 현재 사용중인 실제 메모리의 바이트 수를 알려줍니다. 여기에는 실제 메모리, 장치 버퍼 및 매핑 된 파일이 포함됩니다. 이는 실제 메모리 + 매핑 된 가상 비 시스템 메모리와 같기 때문에 꽤 이상한 그림입니다. 일반적으로이 수치는 완전히 무시해야합니다. 실제로 메모리 누수를 디버깅하는 데 쓸모가 없습니다.

  3. 가상 바이트는 매핑 한 가상 메모리의 총 크기입니다.

차이점은 공유 가상 메모리 (예 : 한 무리의 DLL 파일 또는 전역 힙 블록)를 프로세스에 매핑 한 것입니다. 차이점은 이러한 공유 매핑의 총 크기가 약 1GB임을 나타냅니다. (빠른 시스템 자원의 가용성을 높이기 위해 (이하 "페이지 파일"소위)이의 없음 디스크에 시스템 메모리 페이지의 이동은 스와핑, 함께 할 수있는 아무것도을 가지고 있다는 사실을

유지 램). 이 파일의 이름은이 Windows 영역에서 혼란을 야기하지 않으며, Microsoft가 마침내 "가상 메모리"또는 "페이지 파일"대신 "스왑"이라고 결정할 때 기뻐할 것입니다.

+0

아, 그리고 * 확실히 * 읽으십시오 : http://blogs.technet.com/b/markrussinovich/archive/2008/11/17/3155406.aspx Mark Russinovich는이 저수준 메모리의 "다움"입니다. 물건. – Polynomial

+0

"PAE를 사용하여 3GB로 늘릴 수 있습니다."실제로 PAE를 사용하면 32 비트 OS가 4GB 이상의 물리적 메모리에 액세스 할 수 있습니다. AWE는 32 비트 프로세스가 메모리 창을 사용하여 2GB (또는 3GB와 4GT) 이상의 사용자 메모리에 액세스 할 수있게합니다. 4GT는 응용 프로그램이 가상 주소 공간의 사용자 부분에 최대 3GB의 매핑 된 메모리를 가질 수있게합니다. –

+0

죄송합니다. 내 용어가 섞여있어. 수정할 수정. – Polynomial

2
  1. 가상 크기 설명 : What is private bytes, virtual bytes, working set?
  2. 애플리케이션은 ESP : 2GB에서 가상 크기 제한을 칠 가능성이 높다 (아래 인용문 참조). 당신이 그런 행동을보고 있기 때문에 자신은
  3. /LARGEADDRESSAWARE 자체가 /3GB AKA 4GT로 부팅 시스템이

가상 바이트는이 차지하는 총 가상 주소 공간입니다 사용할 경우에만 Win32 운영 체제에서 응용 프로그램의 가상 크기 제한을 확장 전체 프로세스는 입니다. 이것은 에 메모리 매핑 파일 (공유 DLL)이 포함되어 있지만 대기 목록에있는 데이터 과 이미 페이징 된 데이터가 포함되어 있고 디스크의 페이지 파일에있는 인 작업 집합과 같습니다. 어딘가에. 부하가 많은 시스템의 모든 프로세스가 사용하는 전체 가상 바이트 수는 실제로 시스템이 가지고있는 것보다 훨씬 많은 메모리를 까지 더 합니다.

그래서 관계는 다음과 같습니다

  • 전용 바이트 앱이 실제로 할당 된 것을 있지만, 페이지 파일 사용을 포함한다;
  • 작업 집합은 페이징되지 않은 전용 바이트와 메모리 매핑 파일입니다.
  • 가상 바이트는 작업 세트 + 페이징 전용 바이트 및 대기 목록입니다.
+0

나는 내가 기억할 수있는 것보다 더 많이 링크 한 대답을 읽었지만 여전히 혼란 스럽다. 나는 그 숫자가 왜 그렇게 다른지 구체적으로 알고 싶지만 그 차이를 일으킬 수있는 것이 정확히 무엇인지 알지 못한다면 그것을 식별하기조차 할 수 없다. 대기 목록 및/또는 디스크에있는 페이지의 데이터입니까? 그렇다면 왜 Windows는 실패하지 않고 사용되지 않는 페이지를 없애므로 가상 크기가 줄어들지 않습니까? –

+0

시동기의 간단한 점 : Private Bytes는'new'와'malloc'을 계산합니다 - 성공하면 할당 된 메모리에 대한 유효한 포인터가 있으므로 주소 공간을 소비합니다. 그러나 주소 공간에 매핑 된 모든 코드가 있지만 모든 API DLL뿐만 아니라 주소도 모두 가지고 있습니다. 그리고 그들은 사적인 바이트가 아닙니다. 따라서 프로세스 탐색기 또는 Visual Studio 모듈 창을 열면 프로세스에로드되는 모듈의 수를 볼 수 있으며 사용자가 요청한 차이가 모두 포함됩니다. –

0

단지 코멘트 : 대용량 주소 인식을 활성화하면 운영 체제가 해당 특정 실행 파일에서 생성 된 프로세스의 가상 주소 공간을 일반적인 2 : 2 대신 3 : 1 방식으로 안전하게 나눌 수 있음을 알립니다. 응용 프로그램이 3 : 1 나누기를 지원한다는 것을 명시해야하는 이유는 여러 가지가 있지만 가장 분명한 것은 2 : 2 모드에서 가상 주소의 MSB를 조사하면 주소가 커널 부분에 속하는지 테스트 할 수 있다는 것입니다 가상 주소 공간의 또는 사용자 부분에 할당 할 수 있습니다. 3 : 1에서는 MSB가 가상 주소 공간의 사용자 부분의 1/3에 대해 1이므로이 테스트는 더 이상 유효하지 않습니다. 이 응용 프로그램에서 호출 할 수있는 드라이버는 가능한 3 : 1 나눗셈을 알고 있어야하며 주어진 가상 주소가 not of userspace에 속하는지 테스트하는 다른 방법을 사용해야합니다.

Roman R.이 지적한 바와 같이 3 : 1 VA 공간 분할을 지원하도록 커널에 명시 적으로 명시해야합니다.

+0

/3GB는 많은 RAM이없는 큰 화면 해상도의 클립 보드에 문제가 있음을 명심하십시오. 인쇄 화면이 커널의 클립 보드 버퍼에 맞지 않으므로 작업이 실패합니다. 기묘! – Polynomial

0

내 컴퓨터에서 C/C++/.NET win32 응용 프로그램의 메모리가 부족한 비슷한 문제가 발생했습니다. 2GB의 가상 주소를 모두 소비했습니다. 프로세스 익스플로러는 애플리케이션이 차지하는 메모리가 약 900MB에 불과하기 때문에 Virtual Addresses Exhaustion처럼 보였습니다. VMMap은 1.6GB의 개인 데이터와 약 700MB의 커밋되지 않은 메모리를 보여 줬습니다.

이유는 간단합니다. 응용 프로그램을 테스트하도록 구성된 응용 프로그램 검증 도구 (C : \ Windows \ SysWOW64 \ appverif.exe) (기본 테스트는 vfbasics.dll로 표시). Application Verifier에서 응용 프로그램을 제거한 후 정상적으로 작동했습니다.

관련 문제