메모리 풀링 보통 어떻게 하시나요?

sozu의 이미지

저같은 경우 서버 프로그래밍 할때에는 동적할당을 않하려고 노력하는 편입니다.

주로 사용하는 방법은

1) 매우 큰 메모리 영역을 잡아놓고 직접 할당하여 쓴다.
2) 메모리 풀을 유지하면서 풀이 비면 동적할당 하고 반납받은 메모리는 풀에 넣어 관리한다.

1)번의 경우는 데몬이 돌아가는 동안은 동적할당이 전혀 일어나지 않는다는 장점이 있지만, 메모리 할당 피크가 일어나면 (미리할당한 메모리가 고갈된다면) 문제가 될수 있습니다. (물론 재할당을 하는 방법도 있겠죠.)

2)번의 경우는 유동적인 풀 관리가 가능하지만, 메모리 할당 피크가 일어나면 계속 동적할당을 하여 성능 저하를 초래할수 있습니다.

2번 방법을 사용할때 아래와 같은 컨셉의 코드를 사용하는데 여러분은 어떤방법을 주로 사용하시는지 궁금합니다.

#ifndef		____CHUKMM_H____
#define		____CHUKMM_H____

#include	"HuKMMContainer.h"

template <class T>
class CHuKMM  
{
public:
	CHuKMM() {	
		m_pFreeList = NULL;
	};

	virtual ~CHuKMM() {
		ReleaseObject();
	};

	T * NewObject() {
		CHuKMMContainer<T>		*ret = NULL;
		if (!m_pFreeList)
			ret = new CHuKMMContainer<T>;
		else {
			ret = m_pFreeList;
			m_pFreeList = m_pFreeList->m_pNext;
		}
		return &ret->m_object;
	};

	void DeleteObject(T *pObject) {
		CHuKMMContainer<T>		*p = (CHuKMMContainer<T> *)pObject;
		p->m_pNext = m_pFreeList;
		m_pFreeList = p;
	};

	void ReleaseObject() {
		CHuKMMContainer<T>		*p = NULL;
		while (m_pFreeList) {
			p = m_pFreeList;
			m_pFreeList = m_pFreeList->m_pNext;
			delete p;
		}
	}	

	CHuKMMContainer<T>		*m_pFreeList;
};

#endif 

#ifndef		____CHUKMMCONTAINER_H____
#define		____CHUKMMCONTAINER_H____

template <class T>
class CHuKMMContainer  
{
public:
	T						m_object;
	CHuKMMContainer<T>		*m_pNext;
};

#endif
Forums: 
saxboy의 이미지

어플리케이션의 메모리 사용 빈도에 따라 디자인해야겠지요. 예를 들면 비슷한 종류의 struct를 많이 사용하게 되는 트리나 그래프류라면 (ex. 파서류) struct의 풀을 구성하면 전체적인 성능향상에 큰 도움이 됩니다. 하지만 랜덤한 메모리 사용 패턴을 보이는 경우라면 첫번째가 도움이 될 수도 있겠지요.

이 때 역시나 풀의 용량이 한계에 다다른 경우 어떤 방식으로 다시 allocation을 할 것인지도 문제가 될 수 있는데, 이때의 전체 풀 할당이 모자라는 struct를 하나, 두개씩 할당하는 것은 별로 좋지 않다는 느낌입니다. 한번에 두배씩 다시 할당해 준다거나, 특정한 갯수만큼 다시 할당해준다거나하는 것이 훨씬 낫겠지요.

저는 메모리의 할당이 많은 경우 slab과 비슷한 형태로 원하는 size의 풀을 여러개 관리할 수 있는 형태의 메모리 풀 집합을 만들어 자주 사용합니다. 원하는 type(결국은 size겠지요) 을 register, unregister할 수 있는 형태로 typeid로 할당받을 수 있는 인터페이스를 선호합니다. 장단점은 있지만...

놀라운 것은 이런 풀이 꼭 성능을 높여주지만은 않는다는 것인데, 이것은 특히 해당 플랫폼의 메모리 할당루틴이 비슷한 방식으로 이미 구현되어 있는 경우 심하지요. 오래전에 제가 만든 메모리풀을 리눅스와 솔라리스에서 벤치마크를 해본 적이 있었는데, 리눅스에서는 size에 따라 다르지만 3배 이상의 성능 향상을 보인것에 비해 솔라리스에서는 거의 이득이 없었던 경험이 있습니다. 특히 1K미만의 작은 메모리를 많이 사용하는 경우 양쪽 모두 별 이득이 없었던 것으로 "기억"합니다.

bugiii의 이미지

메모리 풀은 boost 의 pool 을 종종 사용합니다.

http://boost.org/libs/pool/doc/interfaces.html

꽤 쓸만합니다. 요긴하게 사용중입니다.

sozu의 이미지

saxboy wrote:
놀라운 것은 이런 풀이 꼭 성능을 높여주지만은 않는다는 것인데, 이것은 특히 해당 플랫폼의 메모리 할당루틴이 비슷한 방식으로 이미 구현되어 있는 경우 심하지요. 오래전에 제가 만든 메모리풀을 리눅스와 솔라리스에서 벤치마크를 해본 적이 있었는데, 리눅스에서는 size에 따라 다르지만 3배 이상의 성능 향상을 보인것에 비해 솔라리스에서는 거의 이득이 없었던 경험이 있습니다. 특히 1K미만의 작은 메모리를 많이 사용하는 경우 양쪽 모두 별 이득이 없었던 것으로 "기억"합니다.

플랫폼에 따라 달라질수도 있지만, 메모리 할당과 관련된 라이브러리가 어떻게 구현되었느냐에 따라서도 달라질수 있을까요?

예전에 malloc이 구현된 내용을 보면서 풀링에 관련된 내용을 본적이 있습니다. 또한 new를 Overriding 하여 구현된 것도 본적이 있구요.

아무튼 플래폼에 따라 달라질수 있다는 것은 재미있는 이슈인것 같습니다. 저도 시간이 나면 한번 해봐야겠네요~ :P

bugiii wrote:
메모리 풀은 boost 의 pool 을 종종 사용합니다.

http://boost.org/libs/pool/doc/interfaces.html

꽤 쓸만합니다. 요긴하게 사용중입니다.

저의 무지함으로 boost를 최근에 알았습니다. 처음에 본것이 pool 이었는데 한번 써봐야 겠습니다. 8)

-----------
청하가 제안하는 소프트웨어 엔지니어로써 재미있게 사는 법
http://sozu.tistory.com

nomoreid의 이미지

저도 얼마전까지 고민하던 문제라 ^^

http://www-128.ibm.com/developerworks/kr/linux/library/l-memory/

에 가보시면.. 좀 오래 되었지만 메모리 할당에 대한 이야기가 있습니다. 여러가지 할당발법에 대한 비교와 pool 라이브러리에 대한 링크도 있으니 참고 하시고.

또 피크타임시 동적할당러쉬를 하는 문제는.. 위 소스처럼 모자를때 하나만 할당하는게 아니라 일정크기로 한꺼번에 많이 할당하면 해결 할 수 있습니다.
(즉 하나 모자를때를 피크타임으로 보고 그때 현재 pool싸이즈의 10%정도를 미리 할당해 둔다면 피크타임때 동적 할당 러쉬를 피할 수 있습니다.
또 Size가 작은 구조체의 경우 한꺼번에 모아서 할당해 주는게 이익이기도 하구요.)

Never Ending 삽질.

댓글 달기

Filtered HTML

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

BBCode

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param>
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

Textile

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • You can use Textile markup to format text.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Markdown

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • Quick Tips:
    • Two or more spaces at a line's end = Line break
    • Double returns = Paragraph
    • *Single asterisks* or _single underscores_ = Emphasis
    • **Double** or __double__ = Strong
    • This is [a link](http://the.link.example.com "The optional title text")
    For complete details on the Markdown syntax, see the Markdown documentation and Markdown Extra documentation for tables, footnotes, and more.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Plain text

  • HTML 태그를 사용할 수 없습니다.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 줄과 단락은 자동으로 분리됩니다.
댓글 첨부 파일
이 댓글에 이미지나 파일을 업로드 합니다.
파일 크기는 8 MB보다 작아야 합니다.
허용할 파일 형식: txt pdf doc xls gif jpg jpeg mp3 png rar zip.
CAPTCHA
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.