ulimit 管理系统资源的例子
2013-08-12 11:53
363 查看
ulimit 提供了在 shell 进程中限制系统资源的功能。本章列举了一些使用 ulimit 对用户进程进行限制的例子,详述了这些限制行为以及对应的影响,以此来说明 ulimit 如何对系统资源进行限制,从而达到调节系统性能的功能。
使用 ulimit 限制 shell 的内存使用
在这一小节里向读者展示如何使用 – d,– m 和 – v 选项来对 shell 所使用的内存进行限制。
首先我们来看一下不设置 ulimit 限制时调用 ls 命令的情况:
图 2. 未设置 ulimit 时 ls 命令使用情况
大家可以看到此时的 ls 命令运行正常。下面设置 ulimit:
>ulimit -d 1000 -m 1000 -v 1000
这里再温习一下前面章节里介绍过的这三个选项的含义:
-d:设置数据段的最大值。单位:KB。
-m:设置可以使用的常驻内存的最大值。单位:KB。
-v:设置虚拟内存的最大值。单位:KB。
通过上面的 ulimit 设置我们已经把当前 shell 所能使用的最大内存限制在 1000KB 以下。接下来我们看看这时运行 ls 命令会得到什么样的结果:
haohe@sles10-hehao:~/code/ulimit> ls test -l /bin/ls: error while loading shared libraries: libc.so.6: failed to map segment from shared object: Cannot allocate memory
从上面的结果可以看到,此时 ls 运行失败。根据系统给出的错误信息我们可以看出是由于调用 libc 库时内存分配失败而导致的 ls 出错。那么我们来看一下这个 libc 库文件到底有多大:
图 3. 查看 libc 文件大小
从上面的信息可以看出,这个 libc 库文件的大小是 1.5MB。而我们用 ulimit 所设置的内存使用上限是 1000KB,小于 1.5MB,这也就充分证明了 ulimit 所起到的限制 shell 内存使用的功能。
使用 ulimit 限制 shell 创建的文件的大小
接下来向读者展示如何使用 -f 选项来对 shell 所能创建的文件大小进行限制。
首先我们来看一下,没有设置 ulimit -f 时的情况:
图 4. 查看文件
现有一个文件 testFile 大小为 323669 bytes,现在使用 cat 命令来创建一个 testFile 的 copy:
图 5. 未设置 ulimit 时创建复本
从上面的输出可以看出,我们成功的创建了 testFile 的拷贝 newFile。
下面我们设置 ulimt – f 100:
> ulimit -f 100
-f 选项的含义是:用来设置 shell 可以创建的文件的最大值。单位是 blocks。
现在我们再来执行一次相同的拷贝命令看看会是什么结果:
图 6. 设置 ulimit 时创建复本
这次创建 testFile 的拷贝失败了,系统给出的出错信息时文件大小超出了限制。在 Linux 系统下一个 block 的默认大小是 512 bytes。所以上面的 ulimit 的含义就是限制 shell 所能创建的文件最大值为 512 x 100 = 51200 bytes,小于 323669 bytes,所以创建文件失败,符合我们的期望。这个例子说明了如何使用 ulimit 来控制 shell 所能创建的最大文件。
使用 ulimit 限制程序所能创建的 socket 数量
考虑一个现实中的实际需求。对于一个 C/S 模型中的 server 程序来说,它会为多个 client 程序请求创建多个 socket 端口给与响应。如果恰好有大量的 client 同时向 server 发出请求,那么此时 server 就会需要创建大量的 socket 连接。但在一个系统当中,往往需要限制单个 server 程序所能使用的最大 socket 数,以供其他的 server 程序所使用。那么我们如何来做到这一点呢?答案是我们可以通过 ulimit 来实现!细心的读者可能会发现,通过前面章节的介绍似乎没有限制
socket 使用的 ulimit 选项。是的,ulimit 并没有哪个选项直接说是用来限制 socket 的数量的。但是,我们有 -n 这个选项,它是用于限制一个进程所能打开的文件描述符的最大值。在 Linux 下一切资源皆文件,普通文件是文件,磁盘打印机是文件,socket 当然也是文件。在 Linux 下创建一个新的 socket 连接,实际上就是创建一个新的文件描述符。如下图所示(查看某个进程当前打开的文件描述符信息):
图 7. 查看进程打开文件描述符
因此,我们可以通过使用 ulimit – n 来限制程序所能打开的最大文件描述符数量,从而达到限制 socket 创建的数量。
使用 ulimit 限制 shell 多线程程序堆栈的大小(增加可用线程数量)
在最后一个例子中,向大家介绍如何使用 -s(单位 KB)来对线程的堆栈大小进行限制,从而减少整个多线程程序的内存使用,增加可用线程的数量。这个例子取自于一个真实的案例。我们所遇到的问题是系统对我们的多线程程序有如下的限制:
ulimit -v 200000
根据本文前面的介绍,这意味着我们的程序最多只能使用不到 200MB 的虚拟内存。由于我们的程序是一个多线程程序,程序在运行时会根据需要创建新的线程,这势必会增加总的内存需求量。一开始我们对堆栈大小的限制是 1024 (本例子中使用 1232 来说明):
# ulimit – s 1232
当我们的程序启动后,通过 pmap 来查看其内存使用情况,可以看到多个占用 1232KB 的数据段,这些就是程序所创建的线程所使用的堆栈:
图 8. 程序线程所使用的堆栈
每当一个新的线程被创建时都需要新分配一段大小为 1232KB 的内存空间,而我们总的虚拟内存限制是 200MB,所以如果我们需要创建更多的线程,那么一个可以改进的方法就是减少每个线程的固定堆栈大小,这可以通过 ulimit – s 来实现:
# ulimit -s 512
我们将堆栈大小设置为 512KB,这时再通过 pmap 查看一下我们的设置是否起作用:
图 9. 设置 ulimit 后堆栈大小
从上面的信息可以看出,我们已经成功的将线程的堆栈大小改为 512KB 了,这样在总内存使用限制不变的情况下,我们可以通过本小节介绍的方法来增加可以创建的线程数,从而达到改善程序的多线程性能。
使用 ulimit 限制 shell 的内存使用
在这一小节里向读者展示如何使用 – d,– m 和 – v 选项来对 shell 所使用的内存进行限制。
首先我们来看一下不设置 ulimit 限制时调用 ls 命令的情况:
图 2. 未设置 ulimit 时 ls 命令使用情况
大家可以看到此时的 ls 命令运行正常。下面设置 ulimit:
>ulimit -d 1000 -m 1000 -v 1000
这里再温习一下前面章节里介绍过的这三个选项的含义:
-d:设置数据段的最大值。单位:KB。
-m:设置可以使用的常驻内存的最大值。单位:KB。
-v:设置虚拟内存的最大值。单位:KB。
通过上面的 ulimit 设置我们已经把当前 shell 所能使用的最大内存限制在 1000KB 以下。接下来我们看看这时运行 ls 命令会得到什么样的结果:
haohe@sles10-hehao:~/code/ulimit> ls test -l /bin/ls: error while loading shared libraries: libc.so.6: failed to map segment from shared object: Cannot allocate memory
从上面的结果可以看到,此时 ls 运行失败。根据系统给出的错误信息我们可以看出是由于调用 libc 库时内存分配失败而导致的 ls 出错。那么我们来看一下这个 libc 库文件到底有多大:
图 3. 查看 libc 文件大小
从上面的信息可以看出,这个 libc 库文件的大小是 1.5MB。而我们用 ulimit 所设置的内存使用上限是 1000KB,小于 1.5MB,这也就充分证明了 ulimit 所起到的限制 shell 内存使用的功能。
使用 ulimit 限制 shell 创建的文件的大小
接下来向读者展示如何使用 -f 选项来对 shell 所能创建的文件大小进行限制。
首先我们来看一下,没有设置 ulimit -f 时的情况:
图 4. 查看文件
现有一个文件 testFile 大小为 323669 bytes,现在使用 cat 命令来创建一个 testFile 的 copy:
图 5. 未设置 ulimit 时创建复本
从上面的输出可以看出,我们成功的创建了 testFile 的拷贝 newFile。
下面我们设置 ulimt – f 100:
> ulimit -f 100
-f 选项的含义是:用来设置 shell 可以创建的文件的最大值。单位是 blocks。
现在我们再来执行一次相同的拷贝命令看看会是什么结果:
图 6. 设置 ulimit 时创建复本
这次创建 testFile 的拷贝失败了,系统给出的出错信息时文件大小超出了限制。在 Linux 系统下一个 block 的默认大小是 512 bytes。所以上面的 ulimit 的含义就是限制 shell 所能创建的文件最大值为 512 x 100 = 51200 bytes,小于 323669 bytes,所以创建文件失败,符合我们的期望。这个例子说明了如何使用 ulimit 来控制 shell 所能创建的最大文件。
使用 ulimit 限制程序所能创建的 socket 数量
考虑一个现实中的实际需求。对于一个 C/S 模型中的 server 程序来说,它会为多个 client 程序请求创建多个 socket 端口给与响应。如果恰好有大量的 client 同时向 server 发出请求,那么此时 server 就会需要创建大量的 socket 连接。但在一个系统当中,往往需要限制单个 server 程序所能使用的最大 socket 数,以供其他的 server 程序所使用。那么我们如何来做到这一点呢?答案是我们可以通过 ulimit 来实现!细心的读者可能会发现,通过前面章节的介绍似乎没有限制
socket 使用的 ulimit 选项。是的,ulimit 并没有哪个选项直接说是用来限制 socket 的数量的。但是,我们有 -n 这个选项,它是用于限制一个进程所能打开的文件描述符的最大值。在 Linux 下一切资源皆文件,普通文件是文件,磁盘打印机是文件,socket 当然也是文件。在 Linux 下创建一个新的 socket 连接,实际上就是创建一个新的文件描述符。如下图所示(查看某个进程当前打开的文件描述符信息):
图 7. 查看进程打开文件描述符
因此,我们可以通过使用 ulimit – n 来限制程序所能打开的最大文件描述符数量,从而达到限制 socket 创建的数量。
使用 ulimit 限制 shell 多线程程序堆栈的大小(增加可用线程数量)
在最后一个例子中,向大家介绍如何使用 -s(单位 KB)来对线程的堆栈大小进行限制,从而减少整个多线程程序的内存使用,增加可用线程的数量。这个例子取自于一个真实的案例。我们所遇到的问题是系统对我们的多线程程序有如下的限制:
ulimit -v 200000
根据本文前面的介绍,这意味着我们的程序最多只能使用不到 200MB 的虚拟内存。由于我们的程序是一个多线程程序,程序在运行时会根据需要创建新的线程,这势必会增加总的内存需求量。一开始我们对堆栈大小的限制是 1024 (本例子中使用 1232 来说明):
# ulimit – s 1232
当我们的程序启动后,通过 pmap 来查看其内存使用情况,可以看到多个占用 1232KB 的数据段,这些就是程序所创建的线程所使用的堆栈:
图 8. 程序线程所使用的堆栈
每当一个新的线程被创建时都需要新分配一段大小为 1232KB 的内存空间,而我们总的虚拟内存限制是 200MB,所以如果我们需要创建更多的线程,那么一个可以改进的方法就是减少每个线程的固定堆栈大小,这可以通过 ulimit – s 来实现:
# ulimit -s 512
我们将堆栈大小设置为 512KB,这时再通过 pmap 查看一下我们的设置是否起作用:
图 9. 设置 ulimit 后堆栈大小
从上面的信息可以看出,我们已经成功的将线程的堆栈大小改为 512KB 了,这样在总内存使用限制不变的情况下,我们可以通过本小节介绍的方法来增加可以创建的线程数,从而达到改善程序的多线程性能。
相关文章推荐
- 系统资源调优:ulimit
- 统一资源管理与调度平台(系统)介绍
- 一共81个,开源大数据处理工具汇总:查询引擎、流式计算、迭代计算、离线计算、键值存储、表格存储、文件存储、资源管理、日志收集系统、消息系统、分布式服务、集群管理、基础设施、搜索引擎、数据挖掘=监控
- 网络文件资源管理系统的计划设想
- C# ASP.NET 通用权限管理系统组件源码中WCF例子程序服务器端运行详细配置参考
- 某网络建设、运维及光缆资源管理系统项目申报
- 某网络光缆资源管理系统支撑平台简述
- Linux工作管理及系统资源查看
- 基于 HTML5 OpenLayers3 实现 GIS 电信资源管理系统
- 设备资源管理系统-验证码
- 设备资源管理系统-JFreeChart
- 企业级Hadoop 2.x入门系列之四HDFS文件系统和YARN资源管理框架简介
- [U3D + GAD]Egametang开源服务器框架资源管理系统
- IT开源IT资源管理系统-OCS-Inventory-NG+GLP
- 图形化的电力通信光纤资源管理系统概述与功能特点
- 操作系统的资源管理功能有哪几个?其中,哪些功能与计算机系统的硬部件相关?
- C# ASP.NET 通用权限管理系统组件源码中WCF例子程序客户端运行详细配置参考
- 图形化的机房设备与线路资源管理系统设计原则
- CRM 客户资源管理系统(二) 商机管理