2011-08-26 2 views
1

TEST.C :하는 ctypes 및 메모리 누수

#include <stdint.h> 
#include <stdio.h> 
#include <stdlib.h> 
#define MAXFRAGMENTS 4000000 

typedef struct { 
    uint64_t FirstFragmentTimestamp; 
} fragment_t; 

typedef struct { 
    fragment_t** fragments; 
} bts_t; 


bts_t* initialize() { 
    uint32_t i; 
    bts_t* bts; 
    bts = (bts_t *) malloc(sizeof(bts_t)); 
    bts->fragments= (fragment_t **) malloc(sizeof(bts_t *)*MAXFRAGMENTS); 
    for(i=0;i<MAXFRAGMENTS;i++) { 
     (bts->fragments)[i]=(fragment_t *) malloc(sizeof(fragment_t)); 
     (bts->fragments)[i]->FirstFragmentTimestamp = 0; 
    } 
    return bts; 
} 

int fr(bts_t *bts) 
{ 
    uint32_t i; 
    if (bts != NULL) { 
     for(i=0;i<MAXFRAGMENTS;i++) { 
      free(bts -> fragments[i]); 
     } 
     free(bts->fragments); 
    } 
    free(bts); 
    return 1; 
} 


int main() { 
} 

test.py :

from ctypes import * 
import time 

class fragment(Structure): 
    _fields_=[("FirstFragmentTimestamp",c_ulong)] 

class bts(Structure): 
    _fields_=[("fragments",POINTER(POINTER(fragment)))] 


bts_pointer=POINTER(bts) 
bts_library=CDLL("test.so") 
bts_initialize = bts_library.initialize 
bts_initialize.restype = bts_pointer 
bts_free = bts_library.fr 
m = bts_pointer() 
m = bts_initialize() 
bts_free(m) 
print 'done' 
time.sleep(20) 

왜 최고 쇼, 실행 bts_free 후 무료로 무엇을 기억하지 및 스크립트의 끝나기 전에?

답변

1

이것은 유일한 문제는 아니지만 유형이 c_ulong 인 C 유형 unsigned long에 해당하며 유형은 32 비트입니다. 대신 c_ulonglong을 사용해야하며 이는 64 비트입니다.

그것은 윈도우에서 작동
1

(GCC 4.5.3) :

import os 
m = bts_initialize() 
os.system('tasklist /fi "imagename eq python.exe"') 
bts_free(m) 
os.system('tasklist /fi "imagename eq python.exe"') 

출력 : 아담 로젠 필드 말했듯이

Image Name     PID Session Name  Session# Mem Usage 
========================= ====== ================ ======== ============ 
python.exe     3784       0  84,440 K 

Image Name     PID Session Name  Session# Mem Usage 
========================= ====== ================ ======== ============ 
python.exe     3784       0  6,356 K 

, 당신의 구조가 ctypes.c_ulonglong을해야하지만 단지가 될 것입니다 올바르게 액세스하는 데 문제가 있습니다. 나는 왜 당신의 도서관에서 기억이 풀리지 않는지 확신 할 수 없다. 일반적으로 호출자가 메모리를 할당하고 라이브러리에서 라이브러리를 초기화하도록해야한다고 생각합니다.

또한 m = bts_pointer()으로 bts_pointer를 생성하고 mm = bts_initialize()과 함께 새 개체에 즉시 재 할당하는 것이 아무것도 아닙니다. 첫 번째 과제를 삭제할 수 있습니다.

편집 : 조정 할당 및 힙 메모리에 mmap를 방출, 즉 파라미터 M_TRIM_THRESHOLDM_MMAP_THRESHOLDmallopt을 사용으로

봐. 기본값은 brk, sbrk 등의 호출과 관련된 시스템 호출 오버 헤드를 최소화하기 위해 최적화되었을 수 있습니다.

0

Linux 시스템에서는 프로세스가 정지 할 때만 OS에 메모리를 반환하지 않습니다. 이것이 공개되는 메모리를 보지 못하는 이유입니다.

+1

맞지 않습니다. 적어도, 그들은 그렇게 할 수 있습니다. 그리고 만약 내가'malloc()'을 많이 사용하고'free() '하면 프로세스의 크기가 줄어 듭니다. – glglgl