메모리 조각화 란 무엇입니까?


203

C ++ 동적 메모리 할당의 맥락에서 "메모리 조각화"라는 용어가 몇 번 사용되었다고 들었습니다. 메모리 조각화를 처리하는 방법에 대한 몇 가지 질문을 찾았지만 그 자체를 다루는 직접적인 질문을 찾을 수 없습니다. 그래서:

  • 메모리 조각화 란 무엇입니까?
  • 메모리 조각화가 응용 프로그램에 문제가 있는지 어떻게 알 수 있습니까? 어떤 종류의 프로그램이 가장 고통받을까요?
  • 메모리 조각화를 처리하는 좋은 일반적인 방법은 무엇입니까?

또한:

  • 동적 할당을 사용하면 메모리 조각화가 많이 발생할 수 있다고 들었습니다. 이것이 사실입니까? C ++의 맥락에서 모든 표준 컨테이너 (std :: string, std :: vector 등)가 동적 메모리 할당을 사용한다는 것을 알고 있습니다. 프로그램 전체에서 (특히 std :: string) 사용되는 경우 메모리 조각화가 문제가 될 가능성이 더 큽니까?
  • STL이 많은 응용 프로그램에서 메모리 조각화를 어떻게 처리 할 수 ​​있습니까?

1
많은 훌륭한 답변, 모두 감사합니다!
AshleysBrain

4
이미 많은 훌륭한 답변이 있지만 다음은 메모리 조각화가 큰 문제가 된 실제 응용 프로그램 (Firefox)의 사진입니다. blog.pavlov.net/2007/11/10/memory-fragmentation
Marius Gedminas

2
@MariusGedminas 링크가 더 이상 작동하지 않으므로 링크와 함께 간단한 요약을 제공하거나 링크와 함께 요약으로 질문에 대답해야합니다.
katta

물론 그러나 반 십 년간이었다
rsethc

3
아래는 Marius가 게시 한 링크의 업데이트 된 위치입니다. pavlovdotnet.wordpress.com/2007/11/10/memory-fragmentation
TheGameiswar

답변:


312

사용 가능한 메모리의 "큰"(32 바이트) 확장이 있다고 상상해보십시오.

----------------------------------
|                                |
----------------------------------

이제 그 중 일부를 할당하십시오 (5 개의 할당).

----------------------------------
|aaaabbccccccddeeee              |
----------------------------------

이제 첫 번째 네 개의 할당을 해제하고 다섯 번째는 할당하지 마십시오.

----------------------------------
|              eeee              |
----------------------------------

이제 16 바이트를 할당하십시오. 거의 두 배나 많은 공짜가 있어도 할 수 없습니다.

가상 메모리가있는 시스템에서는 조각화가 생각보다 문제가 되지 않습니다 . 큰 할당 은 물리적 주소 공간이 아닌 가상 주소 공간 에서만 인접해야하기 때문 입니다. 예를 들어, 페이지 크기가 2 바이트 인 가상 메모리가 있으면 아무런 문제없이 16 바이트를 할당 할 수 있습니다. 실제 메모리는 다음과 같습니다.

----------------------------------
|ffffffffffffffeeeeff            |
----------------------------------

반면 가상 메모리 (훨씬 더 큰)는 다음과 같습니다.

------------------------------------------------------...
|              eeeeffffffffffffffff                   
------------------------------------------------------...

메모리 조각화의 고전적인 증상은 큰 블록을 할당하려고 시도하는데 메모리가 충분하지 않은 것처럼 보일 수는 없다는 것입니다. 또 다른 가능한 결과는 프로세스가 메모리를 OS로 다시 릴리스 할 수 없다는 것입니다 (이들 블록은 현재 대부분 사용되지 않더라도 OS에서 할당 한 모든 블록에서 여전히 사용중인 객체가 있기 때문에).

C ++에서 메모리 조각화를 방지하는 전술은 크기 및 / 또는 예상 수명에 따라 다른 영역의 객체를 할당하여 작동합니다. 따라서 많은 객체를 생성하고 나중에 모두 함께 파괴하려면 메모리 풀에서 할당하십시오. 그 사이에 다른 할당은 풀에서 나오지 않으므로 메모리에서 할당 사이에 위치하지 않으므로 결과적으로 메모리가 조각화되지 않습니다.

일반적으로 프로그램이 오래 실행되고 많은 할당 및 해제를 수행하지 않는 한 크게 걱정할 필요가 없습니다. 가장 위험에 처한 단기 및 장기 개체의 혼합이있을 때에도 malloc도움을주기 위해 최선을 다할 것입니다. 기본적으로 프로그램에 할당 실패가 발생하거나 예기치 않게 시스템의 메모리가 부족해질 때까지 무시하십시오 (기본 설정은 테스트 중입니다).

표준 라이브러리는 메모리를 할당하는 다른 것보다 나쁘지 않으며 표준 컨테이너에는 모두 Alloc필요한 경우 할당 전략을 미세 조정하는 데 사용할 수 있는 템플릿 매개 변수가 있습니다.


1
각 문자는 바이트입니까? "큰 확장"== 32 바이트를 만들 것입니다. :)
jalf

1
@jalf : 예. 나는 단위를 전혀 언급하지 않았고, 마지막에 실현해야했습니다. 댓글을 달고있는 동안 작업했습니다.
Steve Jessop

"답변"을 선택하는 것은 꽤 어려웠습니다. 여기에 많은 훌륭한 답변이 있습니다. 아직도, 나는 당신이 여기에서 모든 중요한 포인트를 다룬다 고 생각합니다.
AshleysBrain

1
"표준 라이브러리는 메모리를 할당하는 다른 것보다 나쁘지 않습니다." 사실이라면 좋겠지 만 string & vector와 같은 표준 C ++ 템플릿의 구현은 크기를 조정할 때 바람직하지 않은 동작을 가질 수 있습니다. 예를 들어 이전 버전의 Visual Studio에서 std :: string은 기본적으로 realloc 1.5 * current_size (가장 가까운 8 바이트)로 크기가 조정됩니다. 따라서 문자열을 계속 추가하면 특히 임베디드 시스템에서 힙을 매우 쉽게 풀 수 있습니다. 가장 좋은 방어책은 숨겨진 재 할당을 피하기 위해 사용할 공간을 확보하는 것입니다.
locka

1
@ du369 : 가상 메모리는 물리적 메모리만큼 나쁘게 조각화되지 않았습니다. ffffffffffffffff는 가상 메모리에서 연속 할당이지만 물리적 메모리에는 이러한 연속 할당이 존재할 수 없습니다. 그것들이 똑같이 조각화되어 있지만 가상 공간이 훨씬 더 크다는 것을 선호한다면 대신 그 방법으로 자유롭게보십시오. 중요한 실제 포인트는 광대 한 가상 주소 공간을 사용하는 것이 조각화를 무시할 수있을 정도로 충분하기 때문에 16 바이트 할당을 할 수있을 때마다 도움이된다는 것입니다.
Steve Jessop

73

메모리 조각화 란 무엇입니까?

메모리 조각화는 대부분의 메모리가 많은 비 연속 블록 또는 청크에 할당되어 총 메모리의 상당 부분이 할당되지 않지만 대부분의 일반적인 시나리오에서는 사용할 수없는 상태입니다. 이로 인해 메모리 부족 예외 또는 할당 오류가 발생합니다 (예 : malloc은 널을 리턴 함).

이것에 대해 생각하는 가장 쉬운 방법 은 다양한 크기의 그림 을 올려야 하는 큰 빈 벽이 있다고 상상하는 것 입니다. 각 사진은 특정 크기를 차지하며 분명히 작은 조각으로 나눌 수 없습니다. 벽에 빈 자리, 그림의 크기가 필요합니다. 그렇지 않으면 그림을 올릴 수 없습니다. 이제 벽에 그림을 걸기 시작하고 정렬 방법에 신경 쓰지 않으면 곧 부분적으로 그림으로 덮여있는 벽으로 끝나고 빈 자리가 있더라도 대부분의 새로운 그림은 적합하지 않습니다. 사용 가능한 지점보다 크기 때문입니다. 당신은 여전히 ​​작은 그림을 걸 수 있지만 대부분의 사진은 적합하지 않습니다. 따라서 더 많은 공간을 확보하기 위해 이미 벽에있는 것을 다시 정리 (컴팩트)해야합니다.

이제 벽이 당신의 (힙) 기억이고 그림들이 물체라고 상상해보십시오. 그것은 기억 조각화입니다.

메모리 조각화가 응용 프로그램에 문제가 있는지 어떻게 알 수 있습니까? 어떤 종류의 프로그램이 가장 고통받을까요?

메모리 조각화를 처리 할 수 ​​있다는 신호는 특히 사용 된 메모리의 백분율이 높을 때 (하지만 아직 모든 메모리를 다 사용하지는 않았을 때) 많은 할당 오류가 발생하는 경우 기술적으로 충분한 공간이 있어야합니다. 할당하려는 객체에 대해

메모리가 많이 조각화되면 메모리 할당자가 새 객체에 적합한 공간을 찾기 위해 더 많은 작업을 수행해야하기 때문에 메모리 할당이 더 오래 걸릴 수 있습니다. 차례로 많은 메모리 할당이있는 경우 (메모리 조각화로 인해 이후에 발생할 수 있음) 할당 시간이 눈에 띄게 지연 될 수 있습니다.

메모리 조각화를 처리하는 좋은 일반적인 방법은 무엇입니까?

메모리 할당에 좋은 알고리즘을 사용하십시오. 많은 작은 개체에 메모리를 할당하는 대신 작은 개체의 연속 배열에 메모리를 미리 할당하십시오. 메모리 할당시 약간의 낭비가 발생하여 성능이 저하 될 수 있으며 메모리 조각화를 처리해야하는 번거 로움을 덜 수 있습니다.


10
+1. 나는 당신의 "벽에있는 그림들"은유가 정말, 정말 좋고 분명하기 때문에 제안 된 답변을 삭제했습니다.
ctacke

사진의 크기가 다양해야한다는 사실을 강조하면 더 좋겠습니다. 그렇지 않으면 조각화가 발생하지 않습니다.
Björn Pollex

1
흥미롭게도, 요즘 주 메모리 데이터베이스 는 다소 실용화되고 있습니다 (실제로 많은 메모리가 사용 가능함). 이와 관련하여 HDD의 경우 RAM에서 연속 라인을 읽는 것이 데이터가 조각화되는 것보다 훨씬 빠릅니다.
Björn Pollex

1
벽의 그림과 시각적으로 유사하지만 주 메모리는 2 차원이 아닙니다! 그래도 좋은 대답입니다. 감사합니다.
AshleysBrain

24

메모리 조각화는 디스크 조각화와 같은 개념입니다. 사용중인 영역이 서로 밀접하게 묶이지 않기 때문에 낭비되는 공간을 나타냅니다.

10 바이트의 메모리가있는 간단한 장난감 예제를 가정 해 봅시다.

 |   |   |   |   |   |   |   |   |   |   |
   0   1   2   3   4   5   6   7   8   9

이제 A, B 및 C라는 3 개의 3 바이트 블록을 할당하겠습니다.

 | A | A | A | B | B | B | C | C | C |   |
   0   1   2   3   4   5   6   7   8   9

이제 블록 B를 할당 해제하십시오.

 | A | A | A |   |   |   | C | C | C |   |
   0   1   2   3   4   5   6   7   8   9

4 바이트 블록 D를 할당하려고하면 어떻게됩니까? 음, 우리는 무료로 4 바이트의 메모리를 가지고 있지만, 우리는 네 가지가없는 연속 우리는 D를 할당 할 수 있도록 사용 가능한 메모리의 바이트! 우리는 D를 저장할 수 있었지만 메모리를 사용할 수 없었기 때문에 비효율적 인 메모리 사용입니다. 프로그램의 일부 변수가 C를 가리킬 가능성이 높기 때문에 C를 이동하여 공간을 만들 수 없으며 이러한 모든 값을 자동으로 찾아서 변경할 수 없습니다.

그것이 문제인지 어떻게 알 수 있습니까? 가장 큰 징조는 프로그램의 가상 메모리 크기가 실제로 사용중인 메모리 양보다 상당히 크다는 것입니다. 실제 예에서는 10 바이트 이상의 메모리가 있으므로 D는 바이트 9부터 시작하여 할당되고 나중에 3 바이트 이하의 무언가를 할당하지 않는 한 바이트 3-5는 사용되지 않은 상태로 남아 있습니다.

이 예에서 3 바이트는 낭비 할 것이 많지 않지만 2 바이트의 두 할당이 예를 들어 메모리에서 10MB 떨어져 있고 10MB의 블록을 할당해야하는 더 병적 인 경우를 고려하십시오. + 1 바이트 공간이 충분하지 않기 때문에 1 바이트 만 있으면 OS에 10MB 이상의 가상 메모리를 요구해야합니다.

어떻게 방지합니까? 가장 작은 경우는 작은 물체를 자주 만들고 파괴 할 때 발생하는 경향이 있습니다. 그 이유는 많은 작은 물체가 많은 작은 구멍으로 분리되어 "스위스 치즈"효과를 만들어 내기 때문에 그 구멍에 더 큰 물체를 할당 할 수 없기 때문입니다. 이 작업을 수행 할 것임을 알면 효과적인 전략은 큰 메모리 블록을 작은 객체의 풀로 미리 할당 한 다음 해당 블록 내에서 작은 객체의 생성을 수동으로 관리하는 것입니다. 기본 할당자가 처리합니다.

일반적으로 할당이 적을수록 메모리 조각화 가능성이 줄어 듭니다. 그러나 STL은이를 효과적으로 처리합니다. 현재 할당 전체를 사용하는 문자열이 있고 하나의 문자를 추가하면 단순히 현재 길이에 1을 더한 값을 다시 할당하지 않고 길이를 두 배로 늘립니다 . "빈번한 작은 할당 풀"전략의 변형입니다. 문자열은 반복되는 작은 재 할당을 수행하지 않고도 작은 크기의 반복되는 작은 크기를 효율적으로 처리 할 수 ​​있도록 큰 메모리 청크를 가져옵니다. 실제로 모든 STL 컨테이너는 이런 종류의 작업을 수행하므로 일반적으로 STL 컨테이너 자동 재 할당으로 인한 조각화에 대해 너무 걱정할 필요가 없습니다.

물론 STL 컨테이너는 서로 간에 메모리 풀링하지 않지만 , 자주 크기가 조정되는 몇 개의 컨테이너가 아닌 많은 작은 컨테이너를 만드는 경우와 같은 방식으로 조각화를 방지하는 데 관심을 가져야 할 수도 있습니다. 자주 생성되는 작은 객체, STL 여부에 관계없이.


14
  • 메모리 조각화 란 무엇입니까?

메모리 조각화는 이론적으로 사용 가능하더라도 메모리를 사용할 수 없게되는 문제입니다. 조각화에는 두 가지 종류가 있습니다. 내부 조각화 는 할당되었지만 사용할 수없는 메모리입니다 (예 : 메모리가 8 바이트 청크로 할당되지만 4 바이트 만 필요한 경우 프로그램은 반복적으로 단일 연합을 수행합니다). 외부 조각화 는 사용 가능한 메모리가 많은 작은 청크로 분할되어 전체 사용 가능한 메모리가 충분하더라도 큰 할당 요청을 충족시킬 수없는 문제입니다.

  • 메모리 조각화가 응용 프로그램에 문제가 있는지 어떻게 알 수 있습니까? 어떤 종류의 프로그램이 가장 고통받을까요?

프로그램이 실제 paylod 데이터에 필요한 것보다 훨씬 많은 시스템 메모리를 사용하고 메모리 누수를 배제한 경우 메모리 조각화가 문제가됩니다.

  • 메모리 조각화를 처리하는 좋은 일반적인 방법은 무엇입니까?

좋은 메모리 할당기를 사용하십시오. IIRC에서 "최 적합"전략을 사용하는 사람들은 일반적으로 조금 느리면 조각화를 피하는 데 훨씬 뛰어납니다. 그러나 모든 할당 전략에는 병리학 적 최악의 사례가 있음이 밝혀졌습니다. 다행스럽게도 대부분의 응용 프로그램의 일반적인 할당 패턴은 할당자가 처리하기에 비교적 양성입니다. 세부 사항에 관심이 있다면 많은 논문이 있습니다.

  • Paul R. Wilson, Mark S. Johnstone, Michael Neely 및 David Boles. 동적 스토리지 할당 : 설문 조사 및 중요 검토. 1995 년 Springer Verlag LNCS, 1995 년 메모리 관리 국제 워크샵 진행
  • 마크 S. 존스턴, 폴 알 윌슨 메모리 조각화 문제 : 해결 되었습니까? ACM SIG-PLAN 공지, 34 권 3 호, 1999 년 26-36 페이지
  • MR Garey, RL Graham 및 JD Ullman. 메모리 할당 알고리즘의 최악 사례 분석. 1972 년 컴퓨터 이론에 관한 제 4 회 ACM 심포지엄

9

업데이트 :
구글 TCMalloc : 스레드 캐싱의 malloc
것으로 밝혀졌다 가 단편화를 처리에서 꽤 좋은 긴 실행중인 프로세스에.


HP-UX 11.23 / 11.31 ia64에서 메모리 조각화에 문제가있는 서버 응용 프로그램을 개발 중입니다.

이렇게 생겼습니다. 메모리 할당 및 할당 해제를 수행하고 며칠 동안 실행 된 프로세스가있었습니다. 그리고 메모리 누수가 없었지만 프로세스의 메모리 소비는 계속 증가했습니다.

내 경험에 대해. HP-UX에서는 HP-UX gdb를 사용하여 메모리 조각화를 쉽게 찾을 수 있습니다. 중단 점을 설정하고 도달하면이 명령을 실행 info heap하고 프로세스에 대한 모든 메모리 할당 및 총 힙 크기를 확인하십시오. 그런 다음 프로그램을 계속하고 잠시 후에 다시 중단 점에 도달하십시오. 다시하세요 info heap. 힙의 총 크기는 크지 만 개별 할당의 수와 크기는 동일하면 메모리 할당 문제가있을 수 있습니다. 필요한 경우이 시간을 몇 번 확인하십시오.

상황을 개선하는 나의 방법은 이것이었다. HP-UX gdb로 일부 분석을 수행 한 후 std::vector데이터베이스에서 일부 유형의 정보를 저장하는 데 사용했기 때문에 메모리 문제가 발생했음을 알았습니다 . std::vector데이터를 한 블록에 보관해야합니다. 에 따라 몇 개의 컨테이너가있었습니다 std::vector. 이 컨테이너는 정기적으로 재생성되었습니다. 새 레코드가 데이터베이스에 추가 된 후 컨테이너가 재 작성된 경우가 종종있었습니다. 그리고 재생성 된 컨테이너가 더 커서 사용 가능한 여유 메모리 블록에 맞지 않았으며 런타임은 OS에서 새로운 더 큰 블록을 요청했습니다. 결과적으로 메모리 누수가 없었지만 프로세스의 메모리 소비가 증가했습니다. 컨테이너를 교체 할 때 상황이 개선되었습니다. 대신에 std::vector사용하기 시작했습니다std::deque 데이터에 메모리를 할당하는 다른 방법이 있습니다.

HP-UX에서 메모리 조각화를 피하는 방법 중 하나는 Small Block Allocator를 사용하거나 MallocNextGen을 사용하는 것입니다. RedHat Linux에서 기본 할당자는 많은 작은 블록 할당을 처리하는 것처럼 보입니다. Windows에는 Low-fragmentation Heap많은 수의 작은 할당 문제가 있습니다.

내 이해는 STL이 많은 응용 프로그램에서 먼저 문제를 식별해야한다는 것입니다. 메모리 할당 자 (libc와 같은)는 실제로 많은 작은 할당 문제를 처리합니다. std::string예를 들어 서버 응용 프로그램에는 많은 STL 문자열이 있지만 실행에서 볼 info heap때 문제가 발생하지 않습니다. 제 생각에는 자주 큰 할당을 피해야한다는 것입니다. 불행히도 상황을 피할 수없고 코드를 변경해야하는 상황이 있습니다. 필자의 경우와 같이로 전환하면 상황이 개선되었습니다 std::deque. 메모리 조각화를 식별하면 더 정확하게 이야기 할 수 있습니다.


6

메모리 조각화는 다양한 크기의 많은 객체 를 할당하고 할당을 해제 할 때 발생 합니다. 메모리에 다음과 같은 레이아웃이 있다고 가정하십시오.

obj1 (10kb) | obj2(20kb) | obj3(5kb) | unused space (100kb)

이제 obj2릴리스되면 120kb의 사용되지 않는 메모리가 있지만 메모리가 조각화되어 120kb의 전체 블록을 할당 할 수 없습니다.

이러한 영향을 피하기위한 일반적인 기술에는 링 버퍼객체 풀이 포함 됩니다. STL의 맥락에서, 같은 방법 std::vector::reserve()이 도움이 될 수 있습니다.



3

메모리 조각화 란 무엇입니까?

앱이 동적 메모리를 사용하면 메모리 청크를 할당하고 해제합니다. 처음에는 앱의 전체 메모리 공간이 사용 가능한 메모리의 연속 블록입니다. 그러나 다른 크기의 블록을 할당하고 해제하면 메모리가 조각화 되기 시작합니다 . 즉, 큰 연속 사용 가능 블록과 여러 개의 연속 할당 블록 대신 할당되고 사용 가능한 블록이 혼합됩니다. 사용 가능한 블록의 크기는 제한되어 있으므로 재사용하기가 어렵습니다. 예를 들어, 사용 가능한 메모리는 1000 바이트 일 수 있지만 사용 가능한 모든 블록의 길이는 최대 50 바이트이므로 100 바이트 블록에 메모리를 할당 할 수 없습니다.

피할 수 없지만 문제가 적은 조각화의 또 다른 원인은 대부분의 아키텍처에서 메모리 주소가 2, 4, 8 등 바이트 경계에 정렬 되어야한다는 것입니다 (즉, 주소는 2, 4, 8의 배수 여야 함). 예를 들어 3 개의 char필드를 포함하는 구조체가 있더라도 각 필드가 4 바이트 경계에 정렬되어 있기 때문에 구조체의 크기는 3 대신 12가 될 수 있습니다.

메모리 조각화가 응용 프로그램에 문제가 있는지 어떻게 알 수 있습니까? 어떤 종류의 프로그램이 가장 고통받을까요?

분명한 대답은 메모리 부족 예외가 발생한다는 것입니다.

분명히 C ++ 앱에서 메모리 조각화를 감지하는 좋은 방법은 없습니다. 자세한 내용은 이 답변 을 참조하십시오.

메모리 조각화를 처리하는 좋은 일반적인 방법은 무엇입니까?

포인터에서 직접 메모리 주소를 사용하고 특정 메모리 주소를 참조하는 사람을 제어 할 수 없으므로 C ++에서는 어렵습니다. 따라서 할당 된 메모리 블록 (Java 가비지 수집기의 방식)을 다시 정렬하는 것은 옵션이 아닙니다.

사용자 지정 할당자는 더 큰 메모리 청크에서 작은 객체의 할당을 관리하고 해당 청크 내의 여유 슬롯을 재사용하여 도움을 줄 수 있습니다.


3

이것은 인형 용으로 단순화 된 버전입니다.

객체가 메모리에 생성되면 메모리에서 사용 된 부분의 끝에 추가됩니다.

메모리의 사용 된 부분의 끝에 있지 않은 개체가 삭제되면이 개체가 다른 두 개체 사이에 있었으며 "구멍"이 생깁니다.

이것이 바로 조각화입니다.


2

힙에 항목을 추가하려면 컴퓨터가 해당 항목에 맞는 공간을 검색해야합니다. 메모리 풀에서 또는 풀링 된 할당기로 수행되지 않은 동적 할당은 사물을 "느리게"할 수있는 이유입니다. 멀티 스레딩을 수행하는 경우 무거운 STL 응용 프로그램의 경우 Hoard 할당 자 또는 TBB Intel 버전이 있습니다.

이제 메모리가 조각 날 때 두 가지 일이 발생할 수 있습니다.

  1. "큰"객체를 고정하기에 좋은 공간을 찾으려면 더 많은 검색이 필요합니다. 즉, 일정한 조건에서 좋은 연속적인 메모리 덩어리를 찾는 것에 대해 많은 작은 물체가 흩어져 있으면 어려울 수 있습니다 (이것은 극단적입니다).
  2. 메모리는 쉽게 읽을 수있는 엔티티가 아닙니다. 프로세서는 보유 할 수있는 양과 위치로 제한됩니다. 필요한 항목이 하나 있지만 현재 주소가 다른 경우 페이지를 교체하여이 작업을 수행합니다. 지속적으로 페이지를 교환해야하는 경우 처리 속도가 느려질 수 있습니다 (이는 성능에 영향을 미치는 극단적 인 시나리오입니다) . 가상 메모리 에 대한이 게시물을 참조하십시오 .

1

크기가 다른 메모리 블록이 요청되기 때문에 메모리 조각화가 발생합니다. 100 바이트의 버퍼를 고려하십시오. 두 개의 문자를 요청한 다음 정수를 요청합니다. 이제 두 문자를 해제 한 다음 새로운 정수를 요청하지만 해당 정수는 두 문자의 공간에 맞지 않습니다. 해당 메모리는 재 할당하기에 충분한 연속 블록에 없기 때문에 재사용 할 수 없습니다. 게다가, 당신은 당신의 문자에 대해 많은 할당 자 오버 헤드를 호출했습니다.

기본적으로 메모리는 대부분의 시스템에서 특정 크기의 블록으로 만 제공됩니다. 이러한 블록을 분할하면 전체 블록이 해제 될 때까지 다시 결합 할 수 없습니다. 실제로 블록의 작은 부분 만 사용중인 경우 전체 블록이 사용 중일 수 있습니다.

힙 조각화를 줄이는 기본 방법은 더 크고 덜 자주 할당하는 것입니다. 극단적으로, 최소한 자신의 코드 내에서 객체를 이동할 수있는 관리되는 힙을 사용할 수 있습니다. 이것은 어쨌든 메모리 관점에서 문제를 완전히 제거합니다. 분명히 물건을 옮기는 것은 비용이 든다. 실제로 힙에서 매우 적은 양을 할당하는 경우에만 실제로 문제가 있습니다. 연속 컨테이너 (벡터, 문자열 등)를 사용하고 스택에 사람이 할 수있는만큼 할당하는 것이 가장 좋습니다 (항상 성능에 대한 좋은 아이디어). 또한 캐시 일관성을 높여 응용 프로그램을 더 빠르게 실행합니다.

기억해야 할 것은 32 비트 x86 데스크탑 시스템에는 전체 2GB의 메모리가 있으며 4KB "페이지"로 분할되어 있습니다 (페이지 크기는 모든 x86 시스템에서 동일해야 함). 문제를 일으키려면 omgwtfbbq 조각화를 호출해야합니다. 현대 힙은 대부분의 응용 프로그램에 대해 지나치게 크며, 관리되는 힙과 같이이를 견딜 수있는 시스템의 보급이 있기 때문에 조각화는 실제로 과거의 문제입니다.


0

어떤 종류의 프로그램이 가장 고통받을까요?

메모리 조각화와 관련된 문제에 대한 좋은 (= 끔찍한) 예는 Stardock 의 컴퓨터 게임 인 "Elemental : War of Magic" 의 개발 및 릴리스였습니다 .

이 게임은 32 비트 / 2GB 메모리 용으로 구축되었으며 2GB 메모리 내에서 게임을 작동시키기 위해 메모리 관리에서 많은 최적화를 수행해야했습니다. "최적화"는 일정한 할당 및 할당 해제로 이어지면서 시간이 지남에 따라 힙 메모리 조각화가 발생하여 매번 게임이 중단 되었습니다 .

YouTube 에는 "전쟁 이야기"인터뷰 가 있습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.