首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >ctypes和内存泄漏

ctypes和内存泄漏
EN

Stack Overflow用户
提问于 2011-08-27 05:58:31
回答 3查看 1.1K关注 0票数 1

test.c:

代码语言:javascript
运行
复制
#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:

代码语言:javascript
运行
复制
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之后和脚本结束之前,哪些内存没有空闲?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2011-08-27 06:21:41

这可能不是您唯一的问题,但是ctype类型c_ulong对应于只有32位的C类型unsigned long。您应该改用64位的c_ulonglong

票数 1
EN

Stack Overflow用户

发布于 2011-08-27 06:29:33

适用于Windows (gcc 4.5.3):

代码语言:javascript
运行
复制
import os
m = bts_initialize()
os.system('tasklist /fi "imagename eq python.exe"')
bts_free(m)
os.system('tasklist /fi "imagename eq python.exe"')

输出:

代码语言:javascript
运行
复制
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

正如Adam Rosenfield所说,您的结构应该有一个ctypes.c_ulonglong,但这只会是正确访问它的问题。我不确定为什么你的库中的内存没有被释放。不过,总的来说,我认为您应该让调用者分配内存,并让库对其进行初始化。

此外,使用m = bts_pointer()创建bts_pointer并使用m = bts_initialize()立即将m重新分配给新对象也不会有任何效果。您可以删除第一个分配。

编辑:

研究一下如何使用mallopt来调优堆和mmap上的内存分配和释放,特别是参数M_TRIM_THRESHOLDM_MMAP_THRESHOLD。默认值可能经过优化,以最小化与调用brksbrk等相关的系统调用开销。

票数 1
EN

Stack Overflow用户

发布于 2011-08-27 10:38:59

在Linux系统中,进程永远不会将内存交还给操作系统,只有当它们停止时才会。这就是为什么你看不到内存被释放的原因。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/7210965

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档