由买买提看人间百态

boards

本页内容为未名空间相应帖子的节选和存档,一周内的贴子最多显示50字,超过一周显示500字 访问原贴
Programming版 - C++中释放的内存可能立即返回系统吗?
相关主题
请教几个C++问题C++ 中 myobject * a =new myobject[n] 的问题
请教个Bloomberg 的 C++ 题目Test your C++ knowledge...
question overloading ++ errorRe: 110道C++面试题目,你会做多少? (转载)
c++ questionC++问题,confusing...
what is the difference?C++里面
请教一个逻辑地址到物理地址映射的问题 (转载)C++ questions
请教一个关于字符指针的简单问题one question about struct
内存泄露了吗?C++: exception: out-of-order execution?
相关话题的讨论汇总
话题: 内存话题: 系统话题: os话题: 程序话题: 写入
进入Programming版参与讨论
1 (共1页)
h********n
发帖数: 1671
1
忘了以前哪里听到的,一直以为程序里从系统申请的内存不会被释放回系统,直到程序结束才会全部释放,所以程序占用的内存应该是只增的。今天用TOP观察一个程序,发现一个大数组(~400M)被delete后,程序占用的内存减少了大约300M的样子。是不是这些内存真的返回系统了?
一开始我认为可能与内存页管理有关。这个大数组是用来做hash table的,实际上用到的单元并不多(~100K)。所以有可能没用到的页只是在系统登记一下,并没有真正分配。后来我发现这个单元类型是带constructor的,也就是说在用new向系统申请内存的时候,这些单元的constructor都应该被调用了一遍,所以每页内存都应该用到。
接下来不知道我猜得对不对。这个constructor把每个单元都写成0(包括NULL指针),系统在向一块登记过但没有实际分配的内存页写入的时候,如果发现是写入0,可能就不真正执行写入操作。将来从这个位置读取的时候,因为相应内存页从来没有真正分配,得到missed page,所以自动返回0。直到程序向这个位置写入非0数值的时候,系统才真正给这个位置分配内存页。会是这样吗?
X****r
发帖数: 3557
2
Interesting thought :)
But no I don't know any architecture works this way. A page fault is
usually expensive and delay allocating physical memory to trigger more
page faults is almost never worth it.
A memory management library can return memory to the OS, if it feels
like doing so. That's it.

序结束才会全部释放,所以程序占用的内存应该是只增的。今天用TOP观察一个程序,
发现一个大数组(~400M)被delete后,程序占用的内存减少了大约300M的样子。是不
是这些内存真的返回系统了?
到的单元并不多(~100K)。所以有可能没用到的页只是在系统登记一下,并没有真正
分配。后来我发现这个单元类型是带constructor的,也就是说在用new向系统申请内存
的时候,这些单元的constructor都应该被调用了一遍,所以每页内存都应该用到。
,系统在向一块登记过但没有实际分配的内存页写入的时候,如果发现是写入0,可能
就不真正执行写入操作。将来从这个位置读取的时候,因为相应内存页从来没有真正分
配,得到missed page,所以自动返回0。直到程序向这个位置写入非0数值的时候,系
统才真正给这个位置分配内存页。会是这样吗?

【在 h********n 的大作中提到】
: 忘了以前哪里听到的,一直以为程序里从系统申请的内存不会被释放回系统,直到程序结束才会全部释放,所以程序占用的内存应该是只增的。今天用TOP观察一个程序,发现一个大数组(~400M)被delete后,程序占用的内存减少了大约300M的样子。是不是这些内存真的返回系统了?
: 一开始我认为可能与内存页管理有关。这个大数组是用来做hash table的,实际上用到的单元并不多(~100K)。所以有可能没用到的页只是在系统登记一下,并没有真正分配。后来我发现这个单元类型是带constructor的,也就是说在用new向系统申请内存的时候,这些单元的constructor都应该被调用了一遍,所以每页内存都应该用到。
: 接下来不知道我猜得对不对。这个constructor把每个单元都写成0(包括NULL指针),系统在向一块登记过但没有实际分配的内存页写入的时候,如果发现是写入0,可能就不真正执行写入操作。将来从这个位置读取的时候,因为相应内存页从来没有真正分配,得到missed page,所以自动返回0。直到程序向这个位置写入非0数值的时候,系统才真正给这个位置分配内存页。会是这样吗?

h********n
发帖数: 1671
3
谢谢。那有没有一个约定,比如说Linux系统,什么情况下系统会释放内存。是不是从
来没有用过的页会被释放?

【在 X****r 的大作中提到】
: Interesting thought :)
: But no I don't know any architecture works this way. A page fault is
: usually expensive and delay allocating physical memory to trigger more
: page faults is almost never worth it.
: A memory management library can return memory to the OS, if it feels
: like doing so. That's it.
:
: 序结束才会全部释放,所以程序占用的内存应该是只增的。今天用TOP观察一个程序,
: 发现一个大数组(~400M)被delete后,程序占用的内存减少了大约300M的样子。是不
: 是这些内存真的返回系统了?

X****r
发帖数: 3557
4
The memory management library (e.g. the one provides malloc/free)
decides when to return memory to the OS and how much. The library
is either statically or dynamically linked to your application,
thus it should consider part of your application, but not part of
the OS.

【在 h********n 的大作中提到】
: 谢谢。那有没有一个约定,比如说Linux系统,什么情况下系统会释放内存。是不是从
: 来没有用过的页会被释放?

X****r
发帖数: 3557
5
e.g. http://www.google.com/codesearch#Zt3wT8KZVSw/pub/gnu/funet/glibc-2.1.tar.gz%7CsvB89-sMwCU/glibc-2.1/malloc/malloc.c&q=malloc_trim&exact_package=ftp://ftp.funet.fi/pub/gnu/funet/glibc-2.1.tar.gz
Search for 'Malloc_trim' in the page.

【在 X****r 的大作中提到】
: The memory management library (e.g. the one provides malloc/free)
: decides when to return memory to the OS and how much. The library
: is either statically or dynamically linked to your application,
: thus it should consider part of your application, but not part of
: the OS.

h********n
发帖数: 1671
6
这个是GCC使用的算法吗?还是对应某一Linux版本的算法?
我的问题具体说是在Linux上使用GCC编译。前几天就发现从RHEL4u8换成RHEL6后,GCC
版本没变,malloc的算法不一样了,结果一些程序的输出结果也和以前不一样了。其实
两种结果都是正确的,但是头儿要求必须和原来的结果一模一样,很麻烦。
这个问题里的大数组原来是直接从系统调用的,后来头儿要求改用老程序的一个array
类,这样可以和其它部分保持统一,结果最后统计出的内存调用一下子多了许多。

【在 X****r 的大作中提到】
: e.g. http://www.google.com/codesearch#Zt3wT8KZVSw/pub/gnu/funet/glibc-2.1.tar.gz%7CsvB89-sMwCU/glibc-2.1/malloc/malloc.c&q=malloc_trim&exact_package=ftp://ftp.funet.fi/pub/gnu/funet/glibc-2.1.tar.gz
: Search for 'Malloc_trim' in the page.

X****r
发帖数: 3557
7
version of glibc

GCC
array

【在 h********n 的大作中提到】
: 这个是GCC使用的算法吗?还是对应某一Linux版本的算法?
: 我的问题具体说是在Linux上使用GCC编译。前几天就发现从RHEL4u8换成RHEL6后,GCC
: 版本没变,malloc的算法不一样了,结果一些程序的输出结果也和以前不一样了。其实
: 两种结果都是正确的,但是头儿要求必须和原来的结果一模一样,很麻烦。
: 这个问题里的大数组原来是直接从系统调用的,后来头儿要求改用老程序的一个array
: 类,这样可以和其它部分保持统一,结果最后统计出的内存调用一下子多了许多。

t****t
发帖数: 6806
8
your application behaviour should not depend on OS/libc version, if your
application is not OS related.
if you must, you will have to use your own memory management and call kernel
directly to apply for memory.

GCC
array

【在 h********n 的大作中提到】
: 这个是GCC使用的算法吗?还是对应某一Linux版本的算法?
: 我的问题具体说是在Linux上使用GCC编译。前几天就发现从RHEL4u8换成RHEL6后,GCC
: 版本没变,malloc的算法不一样了,结果一些程序的输出结果也和以前不一样了。其实
: 两种结果都是正确的,但是头儿要求必须和原来的结果一模一样,很麻烦。
: 这个问题里的大数组原来是直接从系统调用的,后来头儿要求改用老程序的一个array
: 类,这样可以和其它部分保持统一,结果最后统计出的内存调用一下子多了许多。

h********n
发帖数: 1671
9
不知道哪位老前辈的code,恐怕有20年了。有几百万数据,输出是这些数据计算后的结
果。这些数据的顺序不同,输出结果也不同,但是理论上都是正确的。当初写code的人
为了得到一个canonical order,用数据的指针排序。当时没有问题,现在malloc()算
法一变,数据的指针就变了,输出的结果就和原来不一样了。用户非常不高兴,解释起
来很麻烦,所以头儿要求必须和原来的结果一致。如果只有一个地方用指针排序也就罢
了,问题是这20年来不知道有多少个地方是用指针排序的。

kernel

【在 t****t 的大作中提到】
: your application behaviour should not depend on OS/libc version, if your
: application is not OS related.
: if you must, you will have to use your own memory management and call kernel
: directly to apply for memory.
:
: GCC
: array

c***d
发帖数: 996
10
赞一下。。这些东西你咋记得这么清楚呢。。八辈子也用不着啊。。

【在 X****r 的大作中提到】
: e.g. http://www.google.com/codesearch#Zt3wT8KZVSw/pub/gnu/funet/glibc-2.1.tar.gz%7CsvB89-sMwCU/glibc-2.1/malloc/malloc.c&q=malloc_trim&exact_package=ftp://ftp.funet.fi/pub/gnu/funet/glibc-2.1.tar.gz
: Search for 'Malloc_trim' in the page.

相关主题
请教一个逻辑地址到物理地址映射的问题 (转载)C++ 中 myobject * a =new myobject[n] 的问题
请教一个关于字符指针的简单问题Test your C++ knowledge...
内存泄露了吗?Re: 110道C++面试题目,你会做多少? (转载)
进入Programming版参与讨论
t****t
发帖数: 6806
11
显然并非八辈子也用不着的东西, 都好几拨人问过了

【在 c***d 的大作中提到】
: 赞一下。。这些东西你咋记得这么清楚呢。。八辈子也用不着啊。。
b******n
发帖数: 592
12
如果没有额外的内存管理,大部分内存都会返回系统,当然也存在fragmentation的问
题。Linux系统不会把返回的内存直接free掉,而会用来作cache,所以系统内存的变化
没那么快。大部分时候释放的内存不会直接available。

序结束才会全部释放,所以程序占用的内存应该是只增的。今天用TOP观察一个程序,
发现一个大数组(~400M)被delete后,程序占用的内存减少了大约300M的样子。是不
是这些内存真的返回系统了?
到的单元并不多(~100K)。所以有可能没用到的页只是在系统登记一下,并没有真正
分配。后来我发现这个单元类型是带constructor的,也就是说在用new向系统申请内存
的时候,这些单元的constru
,系统在向一块登记过但没有实际分配的内存页写入的时候,如果发现是写入0,可能
就不真正执行写入操作。将来从这个位置读取的时候,因为相应内存页从来没有真正分
配,得到missed page,所以

【在 h********n 的大作中提到】
: 忘了以前哪里听到的,一直以为程序里从系统申请的内存不会被释放回系统,直到程序结束才会全部释放,所以程序占用的内存应该是只增的。今天用TOP观察一个程序,发现一个大数组(~400M)被delete后,程序占用的内存减少了大约300M的样子。是不是这些内存真的返回系统了?
: 一开始我认为可能与内存页管理有关。这个大数组是用来做hash table的,实际上用到的单元并不多(~100K)。所以有可能没用到的页只是在系统登记一下,并没有真正分配。后来我发现这个单元类型是带constructor的,也就是说在用new向系统申请内存的时候,这些单元的constructor都应该被调用了一遍,所以每页内存都应该用到。
: 接下来不知道我猜得对不对。这个constructor把每个单元都写成0(包括NULL指针),系统在向一块登记过但没有实际分配的内存页写入的时候,如果发现是写入0,可能就不真正执行写入操作。将来从这个位置读取的时候,因为相应内存页从来没有真正分配,得到missed page,所以自动返回0。直到程序向这个位置写入非0数值的时候,系统才真正给这个位置分配内存页。会是这样吗?

l*****o
发帖数: 473
13
小内存不会,大块内存会。
一般的,对于大块内存,是用mmap来直接分配的。不过,这取决于用户空间的内存管理
器。
一般而言,所有内存管理器都是这样设计,因为如果小内存也要每次释放会系统,系统
调用消耗太大。
S*******s
发帖数: 13043
14
the sort by pointer approach sux.
how about you writing another tool to sort the result by the data to make
the two results comparable?

【在 h********n 的大作中提到】
: 不知道哪位老前辈的code,恐怕有20年了。有几百万数据,输出是这些数据计算后的结
: 果。这些数据的顺序不同,输出结果也不同,但是理论上都是正确的。当初写code的人
: 为了得到一个canonical order,用数据的指针排序。当时没有问题,现在malloc()算
: 法一变,数据的指针就变了,输出的结果就和原来不一样了。用户非常不高兴,解释起
: 来很麻烦,所以头儿要求必须和原来的结果一致。如果只有一个地方用指针排序也就罢
: 了,问题是这20年来不知道有多少个地方是用指针排序的。
:
: kernel

l*****o
发帖数: 473
15
One simple solution is to use the same version of library.
If you only need a big array, then you could simply use the mmap system call
. Then it is the same as before.

GCC
array

【在 h********n 的大作中提到】
: 这个是GCC使用的算法吗?还是对应某一Linux版本的算法?
: 我的问题具体说是在Linux上使用GCC编译。前几天就发现从RHEL4u8换成RHEL6后,GCC
: 版本没变,malloc的算法不一样了,结果一些程序的输出结果也和以前不一样了。其实
: 两种结果都是正确的,但是头儿要求必须和原来的结果一模一样,很麻烦。
: 这个问题里的大数组原来是直接从系统调用的,后来头儿要求改用老程序的一个array
: 类,这样可以和其它部分保持统一,结果最后统计出的内存调用一下子多了许多。

l********e
发帖数: 34
16
在网上看到相关的一篇文章,也有人碰到相同的问题,不过不知道GLIBC版本号:
http://hi.baidu.com/flowskyac/blog/item/ef5f641b10c73f1f8618bf8
m*****e
发帖数: 4193
17

This. glibc uses mmap for anything bigger than about 128KB, which can be
easily returned to the OS once freed.
Smaller memory allocations come from the heap and generally cannot be
returned.

【在 l*****o 的大作中提到】
: 小内存不会,大块内存会。
: 一般的,对于大块内存,是用mmap来直接分配的。不过,这取决于用户空间的内存管理
: 器。
: 一般而言,所有内存管理器都是这样设计,因为如果小内存也要每次释放会系统,系统
: 调用消耗太大。

h********n
发帖数: 1671
18
看起来这个与我遇到的情况差不多,大小悬殊的内存间隔调用导致系统在有些情况下不
能有效释放内存。

【在 l********e 的大作中提到】
: 在网上看到相关的一篇文章,也有人碰到相同的问题,不过不知道GLIBC版本号:
: http://hi.baidu.com/flowskyac/blog/item/ef5f641b10c73f1f8618bf8

1 (共1页)
进入Programming版参与讨论
相关主题
C++: exception: out-of-order execution?what is the difference?
[合集] 关于C++ default copy constructor请教一个逻辑地址到物理地址映射的问题 (转载)
抠字眼:assignment and initialize in C++请教一个关于字符指针的简单问题
An empty C structure Question内存泄露了吗?
请教几个C++问题C++ 中 myobject * a =new myobject[n] 的问题
请教个Bloomberg 的 C++ 题目Test your C++ knowledge...
question overloading ++ errorRe: 110道C++面试题目,你会做多少? (转载)
c++ questionC++问题,confusing...
相关话题的讨论汇总
话题: 内存话题: 系统话题: os话题: 程序话题: 写入