Reputation: 24621
test.c:
#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)
Why top show, what memory not free after run bts_free and before end of script ?
Upvotes: 1
Views: 1203
Reputation: 34260
It works on Windows (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"')
Output:
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
As Adam Rosenfield said, your Structure should have a ctypes.c_ulonglong, but that will only be a problem with accessing it correctly. I'm not certain why the memory isn't being freed in your library. In general, though, I think you should let the caller allocate the memory and have the library initialize it.
Also, it's not accomplishing anything to create a bts_pointer with m = bts_pointer()
and immediately reassign m
to a new object with m = bts_initialize()
. You can delete the first assignment.
Edit:
Look into using mallopt to tune the allocation and release of memory on the heap and mmap, specifically the parameters M_TRIM_THRESHOLD
and M_MMAP_THRESHOLD
. The default values are probably optimized to minimize system call overhead associated with calling brk
, sbrk
, etc.
Upvotes: 1
Reputation: 14013
In Linux systems, processes never give memory back to the OS, only when they stop. This is why you don't see the memory being released.
Upvotes: 0
Reputation: 400204
This may not be your only problem, but the ctypes type c_ulong
corresponds to the C type unsigned long
, which is only 32 bits. You should use c_ulonglong
instead, which is 64 bits.
Upvotes: 1