- 论坛徽章:
- 3
|
本帖最后由 gaojl0728 于 2014-07-01 13:59 编辑
今天终于有空整理下在学习和使用linux内核的过程中发现的缺陷,在我忘掉之前记录下来, 欢迎大家讨论。
记忆力有限, 只记得这么多了。
1. 低端内存和高端内存
Linux 内核的物理内存管理分为低端内存和高端内存,我认为这是最不合理的设计了。
32位linux 内核默认低端内存1G(实际上是896M低端内存+128M其他用途的低端内存,但他们本质上都是低端内存),其他的都是高端内存。
没打开PAE的情况下, 低端内存1G, 高端内存最大3G
打开了PAE的情况下, 低端内存1G, 高端内存最大63G
内核在低端内存和高端内存之间安装了一道闸门, 低端内存可以放水给高端内存, 反之则不行, 这就是问题的根源。
一般情况下内核自己使用这1G的低端内存, 应用程序使用最大63G高端内存,
但问题就在于这1G低端内存是被所有的应用程序共享的,一旦系统的压力增大, 这1G的低端内存就会成为瓶颈。
造成结果就是1G的低端内存都快耗光了,而高端内存虽然还剩余很多很多如60G, 但是内核用不了高端内存最终还是OOM了
而且OOM之后最坏的情况是,内核OOM了会干掉占用虚存最大的进程,干掉的进程释放的是高端内存而不是低端内存, 内核最终进入无休止的OOM
在高端内存不够用的情况下, 应用程序也会从低端内存分配内存(放水),这进一步加剧了低端内存的紧张。
从linux 2.6 最后的几个版本开始 32位内核已经可以调整低端内存的大小, 最大可以到3G, 这个问题已经有所缓解,但是跟最大(64G-3G) = 61G的高端内存相比, 低端内存还是很小,还是会成为瓶颈。
在64位linux内核下,高端内存的概念暂时被隐藏了, 但并不代表没有问题, 几十年之后这个问题还是会浮出水面。
我认为最合理的设计就是拿掉高端内存的概念, 用低端内存来管理所有物理内存,内核和应用程序都从低端内存分配内存, 他们直接没有这堵闸门,自然就不会有瓶颈。
讨论没有考虑DMA16和DMA内存区,但这不影响结论。
【补充:】
后来经过大家讨论发现高端内存并不能完全拿掉, 毕竟32位内核虚拟地址空间有限,最大只能访问4G虚拟地址空间, 这是个硬限制(这个瓶颈无论如何也那不掉的),其他的内存必定还是要分给应用程序的, 拿掉高端内存并不能解决任何问题, 对于大物理内存的服务器, 只能推荐使用64位内核。
2. 内核的PageCache
PageCache 真是个好东西, linux内核的许多现代操作系统所具备的高级特性如 文件缓存,动态库,mmap等等都依赖于PageCache, 我本人也十分推崇这种用简单的概念统一实现复杂特性的方法。
但问题是PageCache毫无节制,如果需要他会一直分配内存直到系统内存耗尽最终OOM,这对于需要长时间运行的服务器简直是致命的。
3. linux 进程的主线程栈可以自动增长, 但是pthread线程的栈就不行,
我也是偶然发现的这个问题,根源在于glibc和内核的MAP_STACK不匹配造成的。但是这种不一致会造成理解上的困难。
4. 还是关于栈, linux 进程的主线程栈能够按需自动增长,却不能自动递减, 造成的问题是一旦在栈上分配了大内存, 这块内存在进程退出之前实际上是不释放的。
5. linux 下进程的加载是内核干的,但是动态库却不是, 动态库的加载是glibc自己做的,我理解不了这样分离到底有什么好处么。
glibc的代码可读性实在是不敢恭维, 所以我也一直不清楚动态库是如何加载的。
6. Linux不支持异步IO, 虽然从2.6开始已经部分支持异步IO,但只是在磁盘IO实现了,socket一直没有实现。
作为一个现代操作系统没有异步IO实在是个很大的遗憾,虽然epoll也是个很不错的选择, 但是理论上速度还是比不过异步IO |
评分
-
查看全部评分
|