malloc으로 대량의 메모리할당

seeker의 이미지

#include <stdio.h>
#include <stdlib.h>

int main()
{
char *p= malloc ( 5000000000 ); /* 5Giga bytes */
if ( p )
printf( "Memory Allocation Success\n" );
else
printf( "Memory Allocation Fail\n" );
}

처럼 아무리 크게 할당하여도 메모리할당에러가 발생하지 않는데
왜 그렇죠?

purewell의 이미지

ㅡ_-);

ps -aux 나 윈도그 같은 경우 작업관리자에서

해당 프로세스가 먹고 있는 메모리량을 확인해보시구랴...

malloc의 인자로 들어가는 크기는 size_t 로 되어 있는데

별 말 없으면 int 형일 것이고, 설령 long형이라고 해도

32bit 운영체제에서는 둘다 32bit(4byte)이니

signed형이라면 최대 2,147,483,647까지 먹힐 것이고

unsigned형이라면 4,294,967,295까지 먹힐 것이니

ㅡ_-) 5,000,000,000는 해당 범위를 넘어서서

오버플로우가 되지 않았나 싶소.

Always wish be pure well...

_____________________________
언제나 맑고픈 샘이가...
http://purewell.biz

sandro의 이미지

8)
처음으로 동적 메모리 할당을 알고 나서 그 에러 상황을 확인할때

생각 못하시는 부분이 메모리 swaping 입니다.

자기가 메모리가 지금 현재 사용가능한 메모리 보다 더 많이 할당 받으면

에러가 나겠지 하고 생각하시는데 그렇지 않죠.

왜냐하면 swaping 때문에 현재 메모리 보다 크게 메모리를 할당 받을 수 있습니다.

하지만 swaping도 한계가 있으니 계속 할당 받다 보면 에러가 납니다.

에러를 도출 하려면 이렇게 하면 됩니다.

while(1) {
     char *p= malloc ( 10000000 ); /* 5Giga bytes */ 
     if ( p ) 
        printf( "Memory Allocation Success\n" ); 
     else 
        printf( "Memory Allocation Fail\n" ); 
};

無心

익명 사용자의 이미지

제가 예전에 본 문서에서는, 32비트 시스템에서 가상메모리는 4G로 잡혀 있습니다.
그중 2G 는 커널이 쓰고 2G는 프로그램에 할당되죠.
(2G 메모리를 무조건 할당한다는게 아니라 사용가능한 주소영역이 2G까지 가능하다는 의미입니다.)
따라서 프로그램이 쓸 수 있는 메모리의 총합은 2G이며, 실제 메모리가 부족하더라도 스왑파일을 통해서 2G 까지는 억세스가 가능합니다.
(프로세스에서 쓰레드가 엄청나게 많이 돌아간다면 조금 주의할 필요가 있습니다.)

일단, 이론상으로는 이렇습니다만 틀린부분이 있을지도 모릅니다.

ssoo76의 이미지

malloc()의 prototype은 다음과 같습니다.

void* malloc(size_t size);

size_t는 32bit에서는 4Byte로 64bit에서는 8Byte로 치환됩니다.

위에 purewell 님이 하신 이야기가 맞네요...

참고로 32bit 컴파일 환경에서

printf("%d\n", 5000000000); 을찍어보면 아마도 1이 나올겁니다.

malloc(5000000000)이 malloc(1)이니 당근 성공이겠죠.....[/code]

세상은 하나..........

eungkyu의 이미지

seearomi wrote:
그중 2G 는 커널이 쓰고 2G는 프로그램에 할당되죠.

32비트 시스템은 꼼수를 쓰지 않는 한 4G의 메모리만 사용할 수 있습니다.
리눅스는 그 중 1G를 커널 영역이 차지하고 프로세스의 영역은 3G입니다. :)
실제로 간단히 메모리 주소를 출력하는 프로그램을 짜봐도 알 수 있습니다.
seeker의 이미지

처음 올린 사람인데요.
SunOs 5.8 환경이구요.

64비트 컴파일하니깐, size_t = unsigned long ( 8bytes)로 해서
약, 18 * 10^18까지 가능했구요.
18대신 19로 하니깐 실패하더군요.

그런데 vmstat 1 10 해보니깐,
Swap Free
8G~9G 4G
쯤 나오던데 어떻게 18000000000000000000 이 할당가능한지
궁금합니다.

seeker의 이미지

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>

int main()
{
size_t size;
/* 64bits compile -> unsigned long ,
* 32bits compile -> unsigned int
*/
char *p;

size = 5000000000; /* 5Giga */
fprintf( stderr , "long %d\n" , sizeof (long) );
fprintf( stderr , "size_t %d\n" , sizeof (size_t) );
fprintf( stderr , "size %u\n" , size );
while( 1 )
{
p= malloc ( size );
if ( p )
printf( "Memory Allocation Success\n" );
else
{
perror( "malloc" );
break;
}
}
}

결과
------------
long 4
size_t 4
size 705032704
Memory Allocation Success
Memory Allocation Success
Memory Allocation Success
Memory Allocation Success
Memory Allocation Success
Memory Allocation Success
malloc: Not enough space

이상한건, size_t ( unsigned int )변수에 5Giga 를 할당했음에도
700메가가 할당된것이 이상하고, 6번 반복할당에도 성공했으니깐,
대략 4.2기가를 성공했네요.

vmstat 1 10 하면
procs memory page disk faults cpu
r b w swap free re mf pi po fr de sr s6 s7 s9 s1 in sy cs us sy id
0 0 0 8797936 3857816 18 110 43 2 2 0 0 0 2 1 0 225 1236 295 1 1 98
0 0 0 8766720 3659104 0 11 0 0 0 0 0 0 0 0 0 173 453 286 0 0 100
0 0 0 8766720 3659104 0 0 0 0 0 0 0 0 1 0 0 186 568 281 0 0 100

스왑이 대략 8G, free가 3G쯤 나오네요.

댓글 달기

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
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.