2013-02-20 2 views
9

EOutOfMemory 예외를 잡거나 지금 힙이나 스택이 높은 확률로 손상된 후에 계속 실행하는 것이 합리적입니까? 내가 인해 야생 주소로 쓰는 등의 버그로 이전 메모리 손상으로 인해 발생 EOutOfMemory의 경우를 의미하지 않는다EOutOfMemory 예외를 복구 할 수 있습니까?

, 나는 GetMem를 호출하고 EOutOfMemory을 잡는다 올바른 코드를 의미한다.

+0

경우도 있습니다. 나는 사람들이 Win32 애플 리케이션에서 3GB 메모리 버퍼를 할당하려고 시도하는 것을 보았다. :-) 그래서 그것은 정말로 오류가 발생하기 전에 무엇을하려고했는지에 달려있다. 경우에 따라 복구가 가능합니다. –

답변

6

제 의견으로는 EOutOfMemory에서 계속 시도 할 필요가 없습니다. 내 경험상 힙이 손상되어 향후 오류가 발생할 가능성이 매우 높습니다. 일반적으로 가장 안전한 조치는 프로세스를 종료하는 것입니다.

+0

복구 할 수 없다고 생각되지만 확실하지 않습니다. 필자는 FastMM의 내부와 Windows 메모리 관리에 대해 알지 못합니다. – kludg

+1

우리 서버에서는 EOutOfMemory에 릴리스 된 초기화시 메모리를 요구하므로 예외 및 기타 로깅에 프로세스가 종료되기 전에 기동 할 공간이 있습니다. –

+0

@ MarjanVenema 적어도 다른 코드가 손상된 힙을 사용할 경우 위험합니다. Delphi RTL은 시작할 때 단일 'EOutOfMemory' 인스턴스를 할당하므로 예외를 발생시키기 위해 힙 할당을 할 필요가 없습니다. –

1

일반적으로 복구를 시도 할 필요가 없음에 동의합니다. 그러나 특정 상황에서 유용 할 수 있습니다. 예를 들어, 사용자 선택에 의존하는 많은 양의 메모리를 할당하고 실패 할 경우이를 깨끗이 제거하고 다른 설정으로 다시 시도 할 수 있습니다. 포인트 클라우드를 3D 메시로 변환하는 데는 메모리 요구 사항을 미리 알 수없는 몇 가지 단계가 포함됩니다. 즉각적이고 깨끗한 제거 경로로 복구 할 수있는 단계를 신중하게 코딩하면됩니다. 예를 들어, 일부 데이터 구조는 조각난 메모리 문제를 최소화하기 위해 각 줄을 별도로 할당 한 비트 맵 또는 버퍼입니다. 생성자는 try ... except 처리를 제외하고 EOutOfMemory 예외를 throw하고 소멸자는 이미 할당 된 행을 해제합니다. 나는 그것이 항상 효과가있을 것이라고 보장 할 수는 없지만, 할만 큼 가치있는 일을했다.

관련 문제