malloc_trim

问题描述:c++容器map本身占用内存 大家好,小编来为大家解答以下问题,malloc_trim影响性能吗,malloc_trim 内存整理,现在让我们一起来看看吧!

如何查看堆内内存的碎片情况

malloc_trim的相关图片

C++ 中的容器很好用,比如 vector, map 等,可以动态扩容,自己管理内存,不用用户关心,但是在某些极端情况下,如果内存比较紧张的情况下,可能用户对于这些容器自己的管理规则(主要是释放规则)就不太满意了。

1. erase, clean。

通常在使用 map 的时候直接通过 erase,或者 clean 方法就可以删除数据,如果结合智能指针,用户不用关心内存的问题。但是需要注意的是,调用 erase 或者 clean 方法后,内存并没有立马释放,你仅能认为在某个时刻会自动释放。

下面的代码模拟了这一现象。第一个循环创建了一个 map,第二个循环清理数据。

#include <opencv2/opencv.hpp>。

#include <map>。

using namespace cv;。

using namespace std;。

int main(void)

map<int, shared_ptr<Mat>> m;。

for (int i = 0; i < 1000; ++i)。

{

const char* imagename = "D:\\Code\\test\\image\\t\\bb.png";。

Mat img = imread(imagename);。

shared_ptr<Mat> p = make_shared<Mat>(img);。

m.insert(pair<int, shared_ptr<Mat>>(i, p));。

}

for (int i = 0; i < 1000; ++i)。

{

m.erase(i);

}

cvWaitKey(0);

return 0;

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

创建 map 的过程中内存占用持续上涨。

在这里插入图片描述

但是清理数据过程中并没有立即释放内存。

在这里插入图片描述

但是继续运行,内存被释放了。

在这里插入图片描述

2. 清理内存

在使用容器的过程中,如果存在频繁的插入/清除数据的动作,那么很容易就会造成内存碎片。对于 vector(包括string)可以通过 swap 等手段(参考C++11 中 vector 的基本操作及使用注意事项)来立即释放内存,但是 map 好像并没有(参考:知乎回答)。

Linux 下的 glibc 提供了 malloc_tim() 函数,但是 windows 下并没有。通过 malloc_trim() 函数可以清理内存碎片。

Linux系统里动态申请用户空间内存是怎么回事?的相关图片

Linux系统里动态申请用户空间内存是怎么回事?

如何查看堆内内存的碎片情况 ?

glibc 提供了以下结构和接口来查看堆内内存和 mmap 的使用情况。

struct mallinfo { 。

int arena; /* non-mmapped space allocated from system */ 。

int ordblks; /* number of free chunks */ 。

int smblks; /* number of fastbin blocks */ 。

int hblks; /* number of mmapped regions */ 。

int hblkhd; /* space in mmapped regions */ 。

int usmblks; /* maximum total allocated space */ 。

int fsmblks; /* space available in freed fastbin blocks */ 。

int uordblks; /* total allocated space */ 。

int fordblks; /* total free space */ 。

int keepcost; /* top-most, releasable (via malloc_trim) space */ 。

};

/*返回heap(main_arena)的内存使用情况,以 mallinfo 结构返回 */。

struct mallinfo mallinfo();。

/* 将heap和mmap的使用情况输出到stderr*/。

void malloc_stats();。

可通过以下例子来验证mallinfo和malloc_stats输出结果。

#include <stdlib.h> 。

#include <stdio.h> 。

#include <string.h> 。

#include <unistd.h> 。

#include <sys/mman.h> 。

#include <malloc.h>。

size_t heap_malloc_total, heap_free_total,mmap_total, mmap_count;。

void print_info() 。

{

struct mallinfo mi = mallinfo(); 。

printf("count by itself:\n"); 。

printf("\theap_malloc_total=%lu heap_free_total=%lu heap_in_use=%lu\n\tmmap_total=%lu mmap_count=%lu\n",。

heap_malloc_total*1024, heap_free_total*1024, heap_malloc_total*1024-heap_free_total*1024,。

mmap_total*1024, mmap_count); 。

printf("count by mallinfo:\n"); 。

printf("\theap_malloc_total=%lu heap_free_total=%lu heap_in_use=%lu\n\tmmap_total=%lu mmap_count=%lu\n",。

mi.arena, mi.fordblks, mi.uordblks, 。

mi.hblkhd, mi.hblks); 。

printf("from malloc_stats:\n"); 。

malloc_stats(); 。

#define ARRAY_SIZE 200 。

int main(int argc, char** argv) 。

{

char** ptr_arr[ARRAY_SIZE]; 。

int i;

for( i = 0; i < ARRAY_SIZE; i++) 。

{

ptr_arr[i] = malloc(i * 1024); 。

if ( i < 128) //glibc默认128k以上使用mmap。

{

heap_malloc_total += i; 。

}

else 。

{

mmap_total += i; 。

mmap_count++; 。

}

}

print_info(); 。

for( i = 0; i < ARRAY_SIZE; i++) 。

{

if ( i % 2 == 0) 。

continue; 。

free(ptr_arr[i]);。

if ( i < 128) 。

{

heap_free_total += i; 。

}

else 。

{

mmap_total -= i; 。

mmap_count--; 。

}

}

printf("\nafter free\n"); 。

print_info(); 。

return 1;

该例子第一个循环为指针数组每个成员分配索引位置 (KB) 大小的内存块,并通过 128 为分界分别对 heap 和 mmap 内存分配情况进行计数;

第二个循环是 free 索引下标为奇数的项,同时更新计数情况。通过程序的计数与mallinfo/malloc_stats 接口得到结果进行对比,并通过 print_info打印到终端。

下面是一个执行结果:

count by itself: 。

heap_malloc_total=8323072 heap_free_total=0 heap_in_use=8323072 。

mmap_total=12054528 mmap_count=72 。

count by mallinfo: 。

heap_malloc_total=8327168 heap_free_total=2032 heap_in_use=8325136 。

mmap_total=12238848 mmap_count=72。

from malloc_stats: 。

Arena 0:

system bytes = 8327168 。

in use bytes = 8325136 。

Total (incl. mmap): 。

system bytes = 20566016 。

in use bytes = 20563984 。

max mmap regions = 72 。

max mmap bytes = 12238848。

after free

count by itself: 。

heap_malloc_total=8323072 heap_free_total=4194304 heap_in_use=4128768 。

mmap_total=6008832 mmap_count=36。

count by mallinfo: 。

heap_malloc_total=8327168 heap_free_total=4197360 heap_in_use=4129808 。

mmap_total=6119424 mmap_count=36。

from malloc_stats: 。

Arena 0:

system bytes = 8327168 。

in use bytes = 4129808 。

Total (incl. mmap): 。

system bytes = 14446592 。

in use bytes = 10249232 。

max mmap regions = 72 。

max mmap bytes = 12238848。

由上可知,程序统计和mallinfo 得到的信息基本吻合,其中 heap_free_total 表示堆内已释放的内存碎片总和。

如果想知道堆内究竟有多少碎片,可通过 mallinfo 结构中的 fsmblks 、smblks 、ordblks 值得到,这些值表示不同大小区间的碎片总个数,这些区间分别是 0~80 字节,80~512 字节,512~128k。如果 fsmblks 、 smblks 的值过大,那碎片问题可能比较严重了。

不过, mallinfo 结构有一个很致命的问题,就是其成员定义全部都是 int ,在 64 位环境中,其结构中的 uordblks/fordblks/arena/usmblks 很容易就会导致溢出,应该是历史遗留问题,使用时要注意!

C语言大神求助把两个字符串合并,重复出现的字符保留一个,然后排序后输出。的相关图片

C语言大神求助把两个字符串合并,重复出现的字符保留一个,然后排序后输出。

linux系统用户空间中动态申请内存的函数为malloc (),这个函数在各种操作系统上的使用都是一致的,malloc ()申请的内存的释放函数为free()。对于Linux而言,C库的malloc ()函数一般通过brk ()和mmap ()两个系统调用从内核申请内存。由于用户空间C库的malloc算法实际上具备一个二次管理能力,所以并不是每次申请和释放内存都一定伴随着对内核的系统调用。比如,代码清单11.2的应用程序可以从内核拿到内存后,立即调用free(),由于free()之前调用了mallopt(M_TRIM_THRESHOLD,一1)和mallopt (M_MMAP_MAX,0),这个free ()并不会把内存还给内核,而只是还给了C库的分配算法(内存仍然属于这个进程),因此之后所有的动态内存申请和释放都在用户态下进行。另外,Linux内核总是采用按需调页(Demand Paging),因此当malloc ()返回的时候,虽然是成功返回,但是内核并没有真正给这个进程内存,这个时候如果去读申请的内存,内容全部是0,这个页面的映射是只读的。只有当写到某个页面的时候,内核才在页错误后,真正把这个页面给这个进程。在Linux内核空间中申请内存涉及的函数主要包括kmalloc( ) 、get free pages ( )和vmalloc ()等。kmalloc ()和_get_free pages ()(及其类似函数)申请的内存位于DMA和常规区域的映射区,而且在物理上也是连续的,它们与真实的物理地址只有一个固定的偏移,因此存在较简单的转换关系。而vmalloc()在虚拟内存空间给出一块连续的内存区,实质上,这片连续的虚拟内存在物理内存中并不一定连续,而vmalloc ()申请的虚拟内存和物理内存之间也没有简单的换算关系。

从键盘输入一个字符串,删除字符串中的所有空格后输出的相关图片

从键盘输入一个字符串,删除字符串中的所有空格后输出

代码如下(建议使用C++编译器编译或支持最新C标准的编译器,我在C11标准下通过):

#include <stdio.h>。

#include <string.h>。

#include <malloc.h>。

void Trim(char *str) {。

 char *strTmp = (char *)malloc(sizeof(char) * strlen(str));。

 int i = 1, j = 1;。

 while (str[j] != '\0') {。

  if (str[j] != str[j - 1]) {。

   strTmp[i - 1] = str[j - 1];。

   i++;

   j++;

  } else {

   j++;

  }

 }

 strTmp[i - 1] = str[j - 1];。

 strcpy(str, strTmp);。

 free(strTmp);

int main() {

 char *str1 = "a3B2c1";。

 char *str2 = "Q5BcF570";。

 char *str3 = (char *)malloc(sizeof(char) * (strlen(str1) + strlen(str2)));。

 strcpy(str3, str1);。

 strcat(str3, str2);。

 for (int i = 0; i < strlen(str3); i++)。

  for (int j = 0; j < i; j++)。

   if (str3[i] < str3[j]) {。

    char cTmp = str3[i];。

    str3[i] = str3[j];。

    str3[j] = cTmp;。

   }

 Trim(str3);

   

 printf("%s + %s => %s\n", str1, str2, str3);。

free(str3);

   

 return 0;

用c语言编写程序实现将两个有序的文件进行合并,同时将生成的新文件输出到屏幕上,

#include<stdio.h>。

#include<stdlib.h>。

#include<ctype.h> //isalpha()函数的头文件。

int main()

char *p = NULL;。

p =(char *)malloc(100*sizeof(char));    //将malloc函数返回的void *指针强制转换为char *指针。

printf("请输入字符串:\n");。

gets(p);    //输入字符串。

printf("\n删除了所有空格和标点符号的字符串\n");。

while (*p)

if (isalpha(*p))。

printf("%c", *p);。

p++;

printf("\n");

return 0;

运行效果:

扩展资料:

1、isalpha()函数

作用:判断是否为字母

头文件:#include&lt;ctype.h&gt;。

原型:int isalpha(int ch)。

返回值:若为英文字母,返回非0(小写字母为2,大写字母为1)。若不是字母,返回0。

2、gets()函数

原型:gets(数组名)

作用:把输入的字符串传入给定的数组中。

头文件:#include&lt;stdio.h&gt;。

返回值:正常时返回字符串存放的数组的首地址(指针),错误或遇到EOF时返回NULL。

3、while(*p)

解读:*p内容有值,也就是while(*p)等同于while(*p!='\0'),\0是字符串结束的标志,字符串结束之前都有值。

4、printf("%c",*p)。

等同于putchar(*p),putchar()函数作用是向终端输出一个字符。

5、scanf()函数与gets()函数的区别。

在于输入的字符串是否中间有空格,对于gets()函数,只有遇到'\n'时才停止输入,对于scanf()函数,出现'\n'或空格都停止输入。

原文地址:http://www.qianchusai.com/malloc_trim.html

说明方法写小动物,说明方法写小动物作文

说明方法写小动物,说明方法写小动物作文

ベスベル,しました

ベスベル,しました

competitively,Competitively.

competitively,Competitively.

爱快虚拟线路检测失败,爱快虚拟线路检测失败怎么回事

爱快虚拟线路检测失败,爱快虚拟线路检测失败怎么回事

三年级作文300字题目自拟,三年级作文300字题目自拟题目大全

三年级作文300字题目自拟,三年级作文300字题目自拟题目大全

bucking,buckingham palace是什么意思

bucking,buckingham palace是什么意思

tensorflow2.0安装,tensorflow2.0安装要求

tensorflow2.0安装,tensorflow2.0安装要求

祖国我能为你做些什么作文,祖国我能为你做点什么作文800字

祖国我能为你做些什么作文,祖国我能为你做点什么作文800字

可以自由绘画的软件,自由画画的软件免费下载

可以自由绘画的软件,自由画画的软件免费下载

原著白嘉轩仙草第一次,白嘉轩和仙草生了几个孩子

原著白嘉轩仙草第一次,白嘉轩和仙草生了几个孩子