锁定老帖子 主题:项目事故和安全语言
该帖已经被评为精华帖
|
|
---|---|
作者 | 正文 |
发表时间:2006-09-26
不懂C的人可耻地飘过~
----------- 虽然我不太懂C,C++,但是偶觉得就算程序吃了内存,在没crash之前,系统可用内存还是会越来越少亚,当系统可用内存减少时,明显程序,系统崩溃的几率就大了许多,这个又怎么解释呢? |
|
返回顶楼 | |
发表时间:2006-09-27
wow, 这个帖子真热闹,虽然严重跑题。应该放到综合技术版去。
独狼 写道 虽然我不太懂C,C++,但是偶觉得就算程序吃了内存,在没crash之前,系统可用内存还是会越来越少亚,当系统可用内存减少时,明显程序,系统崩溃的几率就大了许多,这个又怎么解释呢?
操作系统一般都在硬盘上生成一个文件,把它当虚拟内存用。Windows下这个文件叫pagefil.sys,Linux 下叫Swap(?).常用的内存区放在物理内存里,不常用的就放在硬盘上.在应用程序吃内存情况下,操作系统 要向硬盘上的虚拟内存写东西,才能在物理内存里倒出地方。内存耗很大的时候硬盘咕咚咕咚响,原因就是如此。 硬盘的读写起码比物理内存慢十倍,程序就得等,操作系统在一定程度上也得等,这样程序反应时间就会大大 延长。给人的感觉就是“挂”了。如果内存分配失败,JVM会给个OutOfMemoryError, C/C++程序里,会 返回一个指向null了的指针,底下就看程序员自己爱干什么了, 1.可以不检查只管用,那么程序会崩溃, 2.可以检查一下给个错误信息,向输出端发数据也要通过内存,等吧, 3.或者是程序自动退出,那么操作系统得回收内存,资源,等吧。 现在内存便宜,4G内存的机子比比皆是,所以有人认为操作系统没有必要再在硬盘上生个pagefile, 把硬盘当内存用。在Windows底下可以选择不用paging file,在这种情况下,内存吃紧时系统不会再 向硬盘的paging file写东西倒内存,硬盘不会咕咚咕咚响,反应延时这个问题应该减轻,但是内存分配失败会依旧。我的机子没那么多内存,只是推论,没试过。 buaawhl 写道 结果是,我知道有这么回事了。 通过charon给的link,可以知道,通过handle进行堆的管理。以前的malloc API呢? 不过,jack给的那个图里面有Global Memory, Local Memory的区别。Global Memory应该是进程间通信使用的。不知道具体如何管理。 我也没有这些编程环境,也没有尝试。 那篇Managing Heap Memory in Win32 文章是1993年四月三日写的,好老啊,那时NT 3.1还没发布呢。Windows 3.1正大行其道,里面好多名词都是Win 16的历史遗留。 Global Memory和Local Memory的历史由来是因为在Windows 3.1 (Win 16)里面,所有的进程共享一个Global Heap,每个进程有个自己的Local Heap, GlobalAlloc, GlobalFree, LocalAlloc, LocalFree都是在各自的Heap里面分配和释放内存的。和进程间通信毫无关系。 在win 32 NT/2k/XP/2003/Vista里每个进程都有自己的堆,GlobalAlloc和LocalAlloc都是在进程的省缺堆里面分配内存,没什么区别了,留着是为了向后兼容。 API的说明可以在这里查到: http://msdn.microsoft.com/library/default.asp?url=/library/en-us/winprog/winprog/functions_in_alphabetical_order.asp 把Global Memory和Local Memory留给历史吧。 附带的Heap Manager Layers这张图比较新,是从Windows Internals第四版里载下来的。 Jeffrey Richter的Programming Applications for Microsoft Windows, 4th Edition, 是一本 讲Win32编程的权威著作,下面一段话是从第110页摘的:(蓝色的字是我加的,为了阅读流畅。) 引用 While it is true that the process will not have a chance to do its own cleanup (when terminated unexcepted), the operating system does clean up completely after the process so that no operating system resources remain. This means that all memory used by the process is freed, any open files are closed, all kernel objects have their usage counts decremented, and all User and GDI objects are destroyed.
Once a process terminates (no matter how), the system guarantees that the process will not leave any parts of itself behind. There is absolutely no way of knowing whether that process had ever run. A process will leak absolutely nothing once it has terminated. I hope that this is clear. robbin 写道 ddd 写道 我解释不了,不过还是那句话:不能解释不代表一定是apache或php的错。
我连换两个不同的Linux发行版本,并且都update到最新的patch,但是状况依旧,所以我相信kernel没有问题。 我也认为应该不是Linux Kernel的问题,进程消失后分配的内存还在这种事不可能在历史悠久的Unix上出现。一个推测是apache和php启动了别的进程,在吃内存,用top和ps查查?这么严重的问题php论坛没人讨论么? Linux底下的僵尸进程是怎么回事?久闻大名,一直不得其详。 向用Windows的推荐个工具,不过估计你们都知道了,www.sysinternals.com的Process Explorer,一个进程的全貌,净在眼前。(参见附带的截屏图) |
|
返回顶楼 | |
发表时间:2006-09-27
引用 现在内存便宜,4G内存的机子比比皆是,所以有人认为操作系统没有必要搞个虚拟内存,在Windows底下可以不用虚拟内存,在这种情况下,内存吃紧时系统会怎么样,我不知道。从来没试过。
无论用不用虚拟内存,内存不够的时候,对应用程序来说都是一样的。之所以叫虚拟内存,就是因为对应用程序(其实是除了内存管理模块以外的所有程序)来说,是无法区分虚拟内存和物理内存的区别的。 |
|
返回顶楼 | |
发表时间:2006-09-27
》我也认为应该不是Linux Kernel的问题,进程消失后分配的内存还在这种事不可能在历史悠久的Unix上出现。一个推测是apache和php启动了别的进程,在吃内存,用top和ps查查?这么严重的问题php论坛没人讨论么?
robbin说过把所有进程都杀掉了。(其实我也在怀疑他由于操作原因没杀掉所有进程,这个问题可能应该上个资深系统管理员,仅仅是怀疑:)) 》僵尸进程可以google一下,说的比我详细。 |
|
返回顶楼 | |
发表时间:2006-09-27
关于 linux 平台上进程在退出之后,占用的内存仍然没有释放的情况,曾经遇到过。
当时查到的结果是说 linux 会对进程打开过的文件做 cached 。 而且这个 cached 还不是进程级别的,而是操作系统级别的,即使进程退出了, cached 可能仍然存在。 所以就会出现把 apache/PHP 进程 kill 掉了,操作系统中可用的内存仍然很少。 http://www.faqs.org/docs/linux_admin/buffer-cache.html To make the most efficient use of real memory, Linux automatically uses all free RAM for buffer cache, but also automatically makes the cache smaller when programs need more memory. 当时是在做测试,所以找了一个临时的解决方案。 写一个小程序,不断地 malloc 内存,但是不释放,直到 malloc 返回 NULL 就退出。 等这个程序退出之后,操作系统就基本恢复了。 for( ; ; ) { void * buffer = malloc( 1024 ); if( ! buffer ) break; } |
|
返回顶楼 | |
发表时间:2006-09-27
文件内容cached不敢相信,那个文章中说了cached是超级块之类的内核级别的信息,似乎没说cached文件内容。
The cache does not actually buffer files, but blocks, which are the smallest units of disk I/O (under Linux, they are usually 1 kB). This way, also directories, super blocks, other filesystem bookkeeping data, and non-filesystem disks are cached. 如果是cached文件内容本身,那这个系统稳定性就太糟糕了,很容易编个程序让linux内存不足后崩溃。 |
|
返回顶楼 | |
发表时间:2006-09-27
BirdGu 写道 引用 现在内存便宜,4G内存的机子比比皆是,所以有人认为操作系统没有必要搞个虚拟内存,在Windows底下可以不用虚拟内存,在这种情况下,内存吃紧时系统会怎么样,我不知道。从来没试过。
无论用不用虚拟内存,内存不够的时候,对应用程序来说都是一样的。之所以叫虚拟内存,就是因为对应用程序(其实是除了内存管理模块以外的所有程序)来说,是无法区分虚拟内存和物理内存的区别的。 是我的用词不当,我是指有人认为操作系统没有必要再在硬盘上生个pagefile, 把硬盘当内存用。Windows下可以把这个功能关掉。应用程序见到的4G内存,当然都是虚拟内存。原文已经重新编辑过了。 |
|
返回顶楼 | |
发表时间:2006-09-27
ddd 写道 文件内容cached不敢相信,那个文章中说了cached是超级块之类的内核级别的信息,似乎没说cached文件内容。 The cache does not actually buffer files, but blocks, which are the smallest units of disk I/O (under Linux, they are usually 1 kB). This way, also directories, super blocks, other filesystem bookkeeping data, and non-filesystem disks are cached. 关于这句英文,从上下文来看,我的认为是:linux 除了缓存了 super blocks 之外,对于文件的内容也做了部分的缓存,比如刚刚被应用程序读取过或者写过的文件块。但没有缓存整个文件。 ddd 写道 如果是cached文件内容本身,那这个系统稳定性就太糟糕了,很容易编个程序让linux内存不足后崩溃。 cache 会被清除。 When the cache fills up, the data that has been unused for the longest time is discarded and the memory thus freed is used for the new data. |
|
返回顶楼 | |
发表时间:2006-09-27
英文你翻译的似乎对,那个block我直接理解成superblock dentry inode这些东西了,看来也可能是簇s。没注意后面的also这个词语。
cache确实会被清除,我说"如果是cached文件内容本身,那这个系统稳定性就太糟糕了,很容易编个程序让linux内存不足后崩溃"过于思路直接了(其实这个我也知道,但那个时候没想起来:))。 内存被狂占可能确实是cache和buffer的事情,前提是robbin用free命令的时候没注意到-/+ cache/buffer(是这样么?)。 如果计算过-/+ cache/buffer后的结果还是上G,那就不是缓冲的原因了。 |
|
返回顶楼 | |
发表时间:2006-09-27
ddd 写道 英文你翻译的似乎对,那个block我直接理解成superblock dentry inode这些东西了,看来也可能是簇s。没注意后面的also这个词语。
cache确实会被清除,我说"如果是cached文件内容本身,那这个系统稳定性就太糟糕了,很容易编个程序让linux内存不足后崩溃"过于思路直接了(其实这个我也知道,但那个时候没想起来:))。 内存被狂占可能确实是cache和buffer的事情,前提是robbin用free命令的时候没注意到-/+ cache/buffer(是这样么?)。 如果计算过-/+ cache/buffer后的结果还是上G,那就不是缓冲的原因了。 4GB物理内存,运行一天之后关闭所有能关闭的进程,除了关闭不了的kernel进程和ssh之外,没有其他进程在跑,free只剩下100多MB,buffer使用了100多MB,cache使用了400多MB。 Resident memory = 4G - free - buffer - cache = 3.xGB 几个kernel进程和ssh进程可能用掉3.xGB resident内存吗?不是泄漏是什么? |
|
返回顶楼 | |