C/C++ 정적메모리(Static Memory)와 동적메모리의 사용에 대한 조언

프로그래밍/프로그래밍 메모장 2006/06/17 19:37
C/C++ 프로그래머를 위한 조언
정적메모리와 동적메모리의 사용에 대하여

2006년 6월16일 by Xevious7.  http://www.xevious7.com

습관이라는 것은 무서운 것입니다. 또한 유연성 없는 편견이라는 것도
말입니다.

메모리관리는 직접하지 않는 언어를 쓰는 경우라면 이런 문제는
고민할 필요가 없겠지만...
하지만 우리가 C나 C++을 쓸경우 필연적으로 고민해야될 부분이
바로 메모리 문제입니다.

10년 전의 글에서도 저는 밝힌 바 있지만 제가 10년전부터
느꼈던 컴퓨팅의 중요한 법칙중의 하나는 바로 상호교환(Trade-off)
법칙이라는것입니다.
(참조글 : http://www.xevious7.com/6 )

무언가 하나를 위해서 다른 하나를 감수하는 법칙인것이죠.
이것은 다른말로 표현하자면 유연성의 문제입니다.

과거 PC의 메모리가 매우 적었을때도 마찬가지였고 지금처럼 많은경우도
마찬가지 입니다.

메모리를 충분하게 쓰면 속도도 물론 라직도 간단해지고 구현도 쉬우며
심지어 유지보수 또는 디버깅도 엄청나게 쉬워집니다.
다만 비용이 엄청나게 증가하게 됩니다.

그러다보니 적은 메모리를 가지고 적절하게 운영하는 방법을 찾아야 했습니다.
이것이 바로 동적메모리가 나오게 된 배경입니다.

메모리를 필요할때 쓰고 필요없을때는 놓아두자는 것입니다. 말그래도
동적으로 변하는 메모리인것입니다. 참으로 멋찐 개념이죠
메모리가 부족할때 해결할 수 있는 해결책이니깐요. 낭비를 하지 말야야죠
그렇죠?

그러나 여기에 큰 함정이 있습니다. 우리가 실제로 위처럼 그럴 필요성이
있을때만 동적 메모리를 사용하라는 말은 아무도 안해줍니다.
그래서 저는 이렇게 말합니다.

" 제발 항상 동적 메모리를 써야 한다는 편견은 버리십시요. "
"동적메모리는 꼭 써야 할때만 쓰세요."
"정적 메모리를 사용하면 바보같은 프로그래밍을 한다는 유연하지 못한
사고는 과감히 버리십시요. 필요하지도 않은 곳에서 동적메모리로
어렵게 구현하고 어렵게 디버깅하고 어려운 기술을 쓰는것이야 말로
더욱더 바보같은 짓입니다."


한가지 예를 들어봅니다.

패킷을 주고 받는 5000 클라이언트를 수용할 수 있는 서버가 있다고 가정해봅시다.
주고받는 패킷은 최소 30바이트 에서 100 바이트라고 합시다.
클라이언트와 서버간의 인터페이싱을 하기 위한 모듈을 작성한다고 해봅시다.

대부분의 프로그래머들은 동적인 구조로 이문제를 풀려고 합니다.
왜냐구요 그렇게 배웠기 때문입니다. 그리고 그것을 의심하지 않기 때문이죠.
그래서 패킷사이즈도 동적인 버퍼로 클라이언트도 동적인 버퍼로 하는
메모리구조의 데이타 구조를 가지고 함수를 작성하고 구현할 것입니다.

그냥.. 5000개의 100바이트 의 정적인 버퍼를 잡고 할 생각은 하지 않습니다.
자 5000*100 이면  500K 의 메모리를 사용합니다. 0.5M 메모리입니다.
네 결코 적은 메모리는 아닙니다.!!
정말 한 5-6전만 해도 이러면 곤란했을 것입니다.
하지만 요즈음 서버는 대부분 1G 이상의 메모리를 사용합니다.
다른 서비스를 위해서 운영체제또는 다른 부분에서 메모리를 사용하는 메모리를
제외한다고 해서 최소 500M가 이상이 남아돕니다.

상대적으로 우리는 정적 메모리를 사용해도 아무런 무리를 주지 않는 만큼의
적은 메모리를 사용합니다. 0.5M 메모리는 500M의 천분의 1 메모리 이기 때문입니다.

하지만 정적메모리를 선택하지않고 동적메모리를 사용한다면
사용자의 수가 적을때는 분명 메모리를 적게 사용할수 있겠죠?
네 맞습니다.

하지만 여기에 또하나의 큰 함정이 있습니다. 어차피 최대수용 즉 최대치를 가정하고
짜야 하는 만큼 동적메모리를 쓴다고 해도 0.5M의 가용 메모리는 확보해놓아야 합니다.
또한 동적메모리구조이기때문에  유저수가 바뀌거나 패킷사이즈가 바뀔때마다
그리고 사용이 끝날때마다 또 사용을 할때마다
서버에서 이 인터페이스를 쓰는 그 한번 한번의 시간마다  위에서 말한
메모리생성 메모리해제 메모리처리 등등을 컴퓨터에서는 쉬지 않고 해주어야 된다는

사실을 생각해본적이 있습니까?
(패킷을 주고받는 경우 초당 수천번 이상의 체크가 필요한 모듈이 될수도 있습니다.)

그렇습니다. 우리에게 메모리가 충분함에도 불구하고 "동적 메모리를 쓰는 것은 말그대로
엄청난 코스트를 낭비하는 바보같은 짓인것입니다
."

그래서 저는 말합니다.

"동적메모리를 쓸 경우에는 정말로 정말로 메모리가 부족해서 꼭 불가피하게 써야되는지 다시 한번 생각해보십시요" 그럴 경우가 아니라면 우리는 애초부터 어렵게 디자인해야 되고 어렵게 구현해야 되고 어렵게 디버깅해야 되며 또 어렵게 실행되어야 할 프로그램을 만들게 됩니다.  남아도는 메모리를 아끼기 위해서 CPU를 혹사 시키는 것입니다.
CPU뿐이겠습니까? 그냥 큰 정적 배열하나 써서 만들면 술술 나올 프로그램 구조를
동적 메모리를 쓰다고 상대적으로 어렵고 복잡한 프로그램을 만들어야 하는 우리들의
머리도 아까운 것이지요~
사실 동적메모리 사용은 메모리의 효율적 사용이외에는 아무런 이익이 없다는 것입니다.

가끔 정말 몇시간씩 생각해야될 언뜻 보아서는 이해되지 않는 복잡한 형태로
여러가지를 꼬아놓은 수수께기 같은 코드가 있습니다. 하나의 유희로써는
충분히 이해할만 하지만 코딩을 그렇게 한다면 뭔가 문제가 있는게 아닐까요?
우리가 굳이 필요성도 없는데 별 생각없이 동적 메모리 구조를 딱하니 정해놓고
프로그램 디자인을 하는것 자체도 그런 것과 같습니다.

유연성이 없는 프로그래밍은 죽은 프로그래밍입니다. 필요에 의해서 쓰는것은
당연합니다만 예를들어 비디오 메모리는 아직도 사용하는 데이타에 비해서
턱없이 부족합니다. 동적메모리를 쓸수 밖에는 없죠 그때 그때 필요한 데이타만
올려놓아야 하니깐요.

"동적메모리 구조를 쓰려면 반드시 그렇게 써야만 하는가를 먼저 생각해보십니다.
그렇지않다면 정적메모리를 사용하세요."
동적메모리 사용은 메모리의 효율적 사용이외에는 아무런 이익이 없다는 것을
명심하세요."

PS. 물론 이내용도 프로그래밍 월드의 작은 이야기 일 뿐입니다. 정답은 없습니다.
선택은 여러분의 몫입니다.
(동적메모리 사용의 또다른 유용한 면인  복잡한 자료구조의 효율적 구현에
대한 문제는 또다른 이야기 입니다. 사실 그래프나 이진트리를 배열로
구현하려면 돌아버리겠지요)

거의 대부분의 경우 보조기억장치가 주 기억장치보다 적기때문에 기본적으로
데이타보다는 메모리가 적을수 밖에 없기 때문에 아마도 동적 메모리 기법은
계속 남아있을것입니다. 하지만 여전히 골치아프기 때문에 새로운 언어들은
아예 이러한 메모리관리를 언어자체 내부에서 자동관리하며 프로그래머는
메모리에 대해서 고민할 필요가 없게 만들어 버렸습니다.

PS. 가끔 경계를 넘어서 보면 , 우리는 정말 대세에 영향을 주지 않는
작은 부분에 너무 큰 시간을 소비하곤 합니다. 아이러니 한것입니다.
이 동적메모리와 정적메모리 문제처럼 말입니다. 모 한 10시간 회의하고
남는것은 없는 회의라고 할까요. 그러한 함정에 빠지지 않도록 가끔 좀더
넓게 한걸음 물러서 볼 필요가 있습니다.
top

Trackback Address :: http://xevious7.com/trackback/85

  1. 코카스 2006/06/17 21:03 MODIFY/DELETE REPLY

    요즘같은 환경이면 필요한 용량 만큼의 메모리를 쓰기 위해서라기 보다는 메모리를 사용하는 객체의 수명을 관리하기 위해서 더 많이 사용하는 것으로 보입니다. 로컬 정적 메모리는 해당 함수 수행 시간동안에만 유효할테니까요. 전영 정적 메모리를 사용하는 것은 결국 동적 메모리를 사용하는 것이랑 다를 것이 없겠고요

  2. jacking 2006/06/17 21:45 MODIFY/DELETE REPLY

    헐..정적 메모리를 사용하면 바보라는 소리를 하는 분들도 있군요..-_-;;;

    전 서버프로그래머라서 그런지 대부분 정적메모리를 사용하는 편입니다. 머신에서 돌아갈 프로그램을 알수가 있으니 물리적 메모리를 넘지 않도록 조절이 가능하니까요.
    정적메모리를 사용해서 좋은건 동적메모리 사용에 비해 해제나 메모리 단편화에 대해서 신경을 쓰지 않아도 되는 것이고, 잘못된 경우라도 동적메모리는 그대로 프로그램이 종료가 되나 정적메모리인 경우 죽지는 않기 때문이죠(물론 버그는 발생하겠죠;;).

  3. xevious7 2006/06/17 22:42 MODIFY/DELETE REPLY



    jacking // 특히 서버에서는 정적 메모리를 많이 쓰죠. 24시간 계속 돌아야 하니깐
    메모리가 충분하다면 정적메모리 디자인이 훨씬 유리하지요.

  4. xevious7 2006/06/17 22:47 MODIFY/DELETE REPLY

    코카스 // 전역 정적 메모리의 사용을 의미합니다. 이것이 동적 메모리를 사용하는것과 다를게 없다는 것은 이해가 되지 않습니다. 오히려 맨처음 시작할때 필요한만큼 메모리를 활당하고 프로그램이 종료할때 비로서 해제하는 동적 메모리가 무늬만 동적이지 정적 메모리로 보아야 하는게 아닐까요? 제가 의미하는 동적메모리란 프로그램 동작중에 메모리 크기가 변하는 메모리를 의미합니다.

  5. microdev 2006/06/18 09:48 MODIFY/DELETE REPLY

    좋은 정보 얻고 갑니다.

    글을 일고 memory management에 대해 또 다시 한번 생각하게 됐네요.
    시대가 좋아지고 PC성능의 향상으로 정적/동적이란 용어도 사라질듯 하네요^^

  6. Xevious7 2006/06/19 06:38 MODIFY/DELETE REPLY

    microdev // 좋은 글이 되었다니 감사합니다. ~

  7. 동란이 2006/06/20 12:26 MODIFY/DELETE REPLY

    저도 서버프로그래입니다. 저역시 정적으로 메모리를 사용하는데요..

    실제 new, delete의 반복으로 매모리 단편화등의 경험이 계신분 있으신가요?
    어떻게 서버가 반응하는지 알수가 없어서요..

    사실 기존 잘돌아가는 서버들중에 동적메모리를 써서 작업한것들도 잘돌아 가더라구요.
    경험해 보지 않은 문제라 특별히 어떻게 고민해야 될런지..new,delete를 반복해도 서버는 잘돌아 가니 점점 민감하게 생각하던 부분이 누그러 지고 있습니다만..경험을 한번 해보고 싶네요..

  8. xevious7 2006/06/20 13:04 MODIFY/DELETE REPLY

    동란이 // new , delete 반복을 해도 서버는 무리없이 잘 돌아갑니다. 물론 메모리 릭이 안생기도록 제대로 작성했다면 말입니다. 다만 글에서도 밝혔듯이 new및 delete를 반복하면서 생기는 필요없는 cpu부하와 처음 서버작성시와 디버깅시 잘못 코딩을 했을경우 메모리릭 문제에 빠질수 있는 위험성이 있습니다. 애초에 malloc, free, new , delete를 쓰지 않으면 메모리릭 문제자체가 사라지는 잇점도 있는것이죠.

Write a comment