2013-05-22 4 views
4

나는 15000x3000과 같은 큰 뚱뚱한 큰 이미지를 생성해야합니다. 이 이미지를 GDI +, 클래스 Bitmap으로 생성합니다.사용 가능한 인접 메모리 검색

물론 Bitmap을 인스턴스화 할 더 이상 메모리가 없기 때문에 때때로 생성이 실패합니다. 내 목표는 내 사용자에게 생성 할 수있는 이미지의 최대 크기를 알려주는 것입니다. 당신은 크기 15000x3000의 이미지를 생성하기 위해 노력

하지만 메모리가 부족 : 같은

메시지가 보일 것입니다. 최대 크기는 10000x3000 또는 15000x1000입니다. 메시지를 작성하는

생각은 같은 것입니다 :

public bool CanCreateBitmap(Size size, out string message) 
{ 
    long availableMemory = this.GetAvailableContiguousMemory(); 
    long bytesRequiered = (long)size.Width * size.Height * 32; 

    if (availableMemory < bytesRequiered) 
    { 
     var sizeProposal1 = new Size(size.Width, (int)(availableMemory/(32 * size.Width))); 
     var sizeProposal2 = new Size((int)(availableMemory/(32 * size.Height)), size.Height); 

     message = string.Format("You tried to generate an image of size {0}, but there is not enough memory." 
       + Environment.NewLine + "The maximum size available is {1}, or {2}." 
       , size, sizeProposal1, sizeProposal2); 

     return false; 
    } 
    else 
    { 
     message = ""; 
     return true; 
    } 
} 

하지만 기능 GetAvailableContiguousMemory()에 대한 코드를 필요가 없습니다.

.Net의 연속 메모리를 검색하는 방법이 있습니까?
내 목표를 달성하기 위해 올바른 질문을하고 있습니까?

+0

아마도 비트 맵 생성 코드를 try/catch 블록에 넣고 메모리 부족 예외가 발생하면 처리 할 수 ​​있습니까? – dandan78

+0

그건 이미 생각이지만, 여기서 중요한 점은 사용자에게 뭔가를 제안하는 것입니다. 그들은 더 이상 정보가없는 "비트 맵을 만들 수 없습니다"라는 메시지 만 받도록 지루해합니다. –

답변

3

"할당 할 수있는 메모리 용량"질문에 경쟁 조건이 포함되어 있으므로 이러한 기능이 없습니다. 필요한 함수가 있다고 가정하고 호출하면 방대한 양의 메모리를 사용할 수 있다고 알려줍니다. 당신은 그 정보를 사용자에게 전달하고 사용자는 이미지 크기를 결정한 다음 실제로 이미지를 할당하게됩니다. 그러나 다른 프로세스는 사용 가능한 메모리의 절반을 사용하고 OutOfMemoryException을 사용하여 호출이 중단됩니다.

TCP/IP를 통한 미디어 스트리밍에도 비슷한 문제가 있습니다. 비디오 스트리밍을 시작하고 싶지만 꽤 많은 네트워크 대역폭이 필요합니다. 비디오 스트림을 시작하기 만하면 비생산적이기 때문에이 대역폭을 몇 분 후에 사용할 수 있는지 확인하고 싶습니다. 재생이 비디오 길이의 2/3에 도달하면 멈춤. 이제이 문제는 핸드 셰이크 단계에서 네트워크 리소스를 예약함으로써 해결되었습니다. 현재 대역폭을 사용하지 않고 있어도 (비디오 스트리밍은 아직 시작되지 않았습니다.)

음, 일부 모호한 Windows API 호출과 비슷한 효과를 얻으려고 할 수 있습니다. 연구를 시작하십시오 VirtualAlloc 함수에서. 그러나 응용 프로그램이 제대로 작동하더라도 응용 프로그램이 불안정하거나 신뢰할 수 없거나 시스템의 다른 프로세스에 영향을 줄 수 있으므로 해당 경로로 이동하지 않는 것이 좋습니다. 특히 이러한 Windows API는 C++에서 기본적으로 사용되며 .NET에서 관리 힙을 사용하여 작업하고 있습니다. 이러한 접근 방식을 시도하지 않았으므로 결과를 예측할 수 없습니다 (그러나 성공하면 결과를 알려줄 것입니다!).

당신이 물어 보는 것은 디자인 결정입니다. 나는 또한 dandan78의 접근법을 추천 할 것이다 - 사용자가 이미지 크기를 선택하게하고, 그것을 만들려고 시도하고, 시도가 실패하면 오류를 다시 알린다. 사용자는 결국 컴퓨터의 능력에 익숙해지고 시스템을 최대한 많이 초과하지 않습니다.

편집 : 한 가지 더 명심해야합니다. "사용 가능한 연속 메모리"와 같은 것은 없습니다. 운영 체제가 가상 메모리 페이지를 제공합니다. 이 페이지들은 참조 될 때 메모리에로드됩니다. 많은 메모리를 요청하면 가상 메모리 공간에 연속 된 주소가 할당되는 많은 페이지가 생기고 메모리 연속성이라는 인상을 받게됩니다.그러나 일반적으로 new 문으로 반환되는 연속되지 않는 메모리 위치가 있습니다. 메모리 관리자는 관리되는 힙의 첫 번째 사용 가능한 슬롯을 반환하기 때문입니다. 이 노트가이 질문에 대한 주제와 관련이 없다는 것을 알고 있지만, 이와 같은 상황에서 메모리 관리 전략을 염두에 두지는 않을 것입니다.

+0

함수가 true를 반환하더라도 생성이 실패 할 수 있습니다. 하지만 이미 인스턴스를 만들 때 try catch를 추가합니다. 이 기능은 사용자를위한 조언을 추가하기위한 것입니다. –

+0

내가 필요한 것을 이해합니다. 당신이 명심해야 할 또 하나의 사실 : "가용 연속 메모리"와 같은 것은 없다. 운영 체제가 가상 메모리 페이지를 제공합니다. 이 페이지들은 참조 될 때 메모리에로드됩니다. 많은 메모리를 요청하면 가상 메모리 공간에 연속 된 주소가 할당되는 많은 페이지가 생기고 메모리 연속성이라는 인상을 받게됩니다. 인접하지 않은 메모리를 갖는 유일한 방법은 많은 양의 작은 오브젝트를 할당 할 때 당신을 때리는 이전에 할당 된 페이지로부터 메모리 덩어리를받는 것입니다. –

+0

@sysexpand : 할당 작업 방법에 대한 의견은 귀하의 답변에 더할 나위없이 좋을 것입니다. –

3

이러한 알림은 실제로 사용자를 돕지 않는 반창고입니다. 그들은 정말로 커다란 비트 맵을 만들고 싶었고 임의로 작은 비트 맵을 원했던 것이 아닙니다. 어쨌든 이렇게하고 싶다면 가상 주소 공간을 걷고 아직 매핑되지 않은 청크를 찾으려면 VirtualQuery를 고정해야합니다.

요즘에는이 문제가 발생하지 않으므로 프로젝트의 플랫폼 대상 설정을 AnyCPU로 변경하면 프로그램에서 64 비트 운영 체제에서 사용 가능한 가상 메모리 공간을 사용할 수 있습니다.

관련 문제