概述

[root@localhost ~]# rpm -qa|grep bash
bash-4.1.2-15.el6_4.x86_64

linux limits.conf 配置 limits.conf 文件实际是 Linux PAM(插入式认证模块,Pluggable Authentication Modules)中 pam_limits.so 的配置文件,而且只针对于单个会话。

要使 limits.conf 文件配置生效,必须要确保 pam_limits.so 文件被加入到启动文件中。查看 /etc/pam.d/login 文件中有:
session required /lib/security/pam_limits.so

系统性能一直是一个受关注的话题,如何通过最简单的设置来实现最有效的性能调优,如何在有限资源的条件下保证程序的运作,ulimit 是我们在处理这些问题时,经常使用的一种简单手段。
ulimit 是一种 linux 系统的内建功能,它具有一套参数集,用于为由它生成的 shell 进程及其子进程的资源使用设置限制。本文将在后面的章节中详细说明 ulimit 的功能,使用以及它的影响,
并以具体的例子来详细地阐述它在限制资源使用方面的影响。

假设有这样一种情况,当一台 Linux 主机上同时登陆了 10 个人,在系统资源无限制的情况下,这 10 个用户同时打开了 500 个文档,而假设每个文档的大小有 10M,这时系统的内存资源就会受到巨大的挑战。
而实际应用的环境要比这种假设复杂的多,例如在一个嵌入式开发环境中,各方面的资源都是非常紧缺的,对于开启文件描述符的数量,分配堆栈的大小,CPU 时间,虚拟内存大小,等等,
都有非常严格的要求。资源的合理限制和分配,不仅仅是保证系统可用性的必要条件,也与系统上软件运行的性能有着密不可分的联系。这时,ulimit 可以起到很大的作用,它是一种简单并且有效的实现资源限制的方式。
ulimit 用于限制 shell 启动进程所占用的资源,支持以下各种类型的限制:所创建的内核文件的大小、进程数据块的大小、Shell 进程创建文件的大小、内存锁住的大小、常驻内存集的大小、
打开文件描述符的数量、分配堆栈的最大大小、CPU 时间、单个用户的最大线程数、Shell 进程所能使用的最大虚拟内存。同时,它支持硬资源和软资源的限制。
作为临时限制,ulimit 可以作用于通过使用其命令登录的 shell 会话,在会话终止时便结束限制,并不影响于其他 shell 会话。而对于长期的固定限制,
ulimit 命令语句又可以被添加到由登录 shell 读取的文件中,作用于特定的 shell 用户。

解释

linux下默认是不产生core文件的,要用ulimit -c unlimited放开
ulimit 通过一些参数选项来管理不同种类的系统资源。
ulimit 命令的格式为:ulimit [options] [limit]

表 1. ulimit 参数说明

选项 [options] 含义 例子
-H 设置硬资源限制,一旦设置不能增加。                 ulimit – Hs 64;限制硬资源,线程栈大小为 64K。
-S 设置软资源限制,设置后可以增加,但是不能超过硬资源设置。     ulimit – Sn 32;限制软资源,32 个文件描述符。
-a 显示当前所有的 limit 信息。                      ulimit – a;显示当前所有的 limit 信息。
-c 最大的 core 文件的大小, 以 blocks 为单位。             ulimit – c unlimited; 对生成的 core 文件的大小不进行限制。
-d 进程最大的数据段的大小,以 Kbytes 为单位。             ulimit - d unlimited;对进程的数据段大小不进行限制。
-f 进程可以创建文件的最大值,以 blocks 为单位。             ulimit – f 2048;限制进程可以创建的最大文件大小为 2048 blocks。
-l 最大可加锁内存大小,以 Kbytes 为单位。               ulimit – l 32;限制最大可加锁内存大小为 32 Kbytes。
-m 最大内存大小,以 Kbytes 为单位。                  ulimit – m unlimited;对最大内存不进行限制。
-n 可以打开最大文件描述符的数量。                    ulimit – n 128;限制最大可以使用 128 个文件描述符。
-p 管道缓冲区的大小,以 Kbytes 为单位。                ulimit – p 512;限制管道缓冲区的大小为 512 Kbytes。
-s 线程栈大小,以 Kbytes 为单位。                    ulimit – s 512;限制线程栈的大小为 512 Kbytes。
-t 最大的 CPU 占用时间,以秒为单位。                    ulimit – t unlimited;对最大的 CPU 占用时间不进行限制。
-u 用户最大可用的进程数。                    ulimit – u 64;限制用户最多可以使用 64 个进程。
-v 进程最大可用的虚拟内存,以 Kbytes 为单位。         ulimit – v 200000;限制最大可用的虚拟内存为 200000 Kbytes。

样例:

在用户的启动脚本中
如果用户使用的是 bash,就可以在用户的目录下的 .bashrc 文件中,加入 ulimit -u 64,来限制用户最多可以使用 64 个进程。此外,可以在与 .bashrc 功能相当的启动脚本中加入 ulimt。

在应用程序的启动脚本中
如果用户要对某个应用程序 myapp 进行限制,可以写一个简单的脚本 startmyapp。
ulimit -s 512
myapp
以后只要通过脚本 startmyapp 来启动应用程序,就可以限制应用程序 myapp 的线程栈大小为 512K。

直接在控制台输入
user@tc511-ui:~>ulimit -p 256
限制管道的缓冲区为 256K。

用户进程的有效范围
ulimit 作为对资源使用限制的一种工作,是有其作用范围的。那么,它限制的对象是单个用户,单个进程,还是整个系统呢?事实上,ulimit 限制的是当前 shell 进程以及其派生的子进程。
举例来说,如果用户同时运行了两个 shell 终端进程,只在其中一个环境中执行了 ulimit -s 100,则该 shell 进程里创建文件的大小收到相应的限制,而同时另一个 shell 终端包括其上运行的子程序都不会受其影响:

那么,是否有针对某个具体用户的资源加以限制的方法呢?答案是有的,方法是通过修改系统的 /etc/security/limits 配置文件。该文件不仅能限制指定用户的资源使用,
还能限制指定组的资源使用。该文件的每一行都是对限定的一个描述,格式如下:
<domain> <type> <item> <value>
domain 表示用户或者组的名字,还可以使用 * 作为通配符。Type 可以有两个值,soft 和 hard。Item 则表示需要限定的资源,可以有很多候选值,如 stack,cpu,nofile 等等,
分别表示最大的堆栈大小,占用的 cpu 时间,以及打开的文件数。通过添加对应的一行描述,则可以产生相应的限制。例如:
* hard noflle 100
该行配置语句限定了任意用户所能创建的最大文件数是 100。

现在已经可以对进程和用户分别做资源限制了,看似已经足够了,其实不然。很多应用需要对整个系统的资源使用做一个总的限制,这时候我们需要修改 /proc 下的配置文件。
/proc 目录下包含了很多系统当前状态的参数,例如 /proc/sys/kernel/pid_max,/proc/sys/net/ipv4/ip_local_port_range 等等,从文件的名字大致可以猜出所限制的资源种类。
由于该目录下涉及的文件众多,在此不一一介绍。有兴趣的读者可打开其中的相关文件查阅说明。

案例:
ulimit 提供了在 shell 进程中限制系统资源的功能。本章列举了一些使用 ulimit 对用户进程进行限制的例子,详述了这些限制行为以及对应的影响,以此来说明 ulimit 如何对系统资源进行限制,从而达到调节系统性能的目的。

使用 ulimit 限制 shell 的内存使用
在这一小节里向读者展示如何使用 -d,-m 和 -v 选项来对 shell 所使用的内存进行限制。
限制前
[root@localhost lianxi]# echo "testwwww" >test
[root@localhost lianxi]# ll test
-rw-r--r--. 1 root root 9 May 10 10:21 test
限制后
[root@localhost lianxi]# ulimit -d 1000 -m 1000 -v 1000
[root@localhost lianxi]# ll test
Segmentation fault
以上是在centos6.5-64位上运行的,与其它版本的报错信息可能不一致

通过上面的 ulimit 设置我们已经把当前 shell 所能使用的最大内存限制在 1000KB 以下
从上面的结果可以看到,此时 ls 运行失败。根据系统给出的错误信息我们可以看出是由于调用 libc 库时内存分配失败而导致的 ls 出错。那么我们来看一下这个 libc 库文件到底有多大:
从上面的信息可以看出,这个 libc 库文件的大小是 1.5MB。而我们用 ulimit 所设置的内存使用上限是 1000KB,小于 1.5MB,这也就充分证明了 ulimit 所起到的限制 shell 内存使用的功能。

使用 ulimit 限制 shell 创建的文件的大小
接下来向读者展示如何使用 -f 选项来对 shell 所能创建的文件大小进行限制。
限制前 可以创建任何大小的文件
[root@localhost lianxi]# cp win2k3_r2_ent_sp1_cd2.iso test1
[root@localhost lianxi]# ll
total 273980
-rw-r--r--. 1 root root 9 May 10 10:21 test
-rw-r--r--. 1 root root 140273664 May 10 10:38 test1
-rw-r--r--. 1 root root 140273664 Jul 31 2006 win2k3_r2_ent_sp1_cd2.iso
限制后
[root@localhost lianxi]# ulimit -f 100000
[root@localhost lianxi]# cp win2k3_r2_ent_sp1_cd2.iso test3
File size limit exceeded

使用 ulimit 限制程序所能创建的 socket 数量
考虑一个现实中的实际需求。对于一个 C/S 模型中的 server 程序来说,它会为多个 client 程序请求创建多个 socket 端口给与响应。如果恰好有大量的 client 同时向 server 发出请求,
那么此时 server 就会需要创建大量的 socket 连接。但在一个系统当中,往往需要限制单个 server 程序所能使用的最大 socket 数,以供其他的 server 程序所使用。
那么我们如何来做到这一点呢?答案是我们可以通过 ulimit 来实现!细心的读者可能会发现,通过前面章节的介绍似乎没有限制 socket 使用的 ulimit 选项。是的,
ulimit 并没有哪个选项直接说是用来限制 socket 的数量的。但是,我们有 -n 这个选项,它是用于限制一个进程所能打开的文件描述符的最大值。在 Linux 下一切资源皆文件,
普通文件是文件,磁盘打印机是文件,socket 当然也是文件。在 Linux 下创建一个新的 socket 连接,实际上就是创建一个新的文件描述符。

776 ? 00:00:00 rsyslogd
[root@localhost fd]# cd /proc/776/fd
[root@localhost fd]# ll
total 0
lrwx------. 1 root root 64 May 10 10:53 0 -> socket:[10173]
l-wx------. 1 root root 64 May 10 10:53 1 -> /var/log/secure
l-wx------. 1 root root 64 May 10 10:53 2 -> /var/log/maillog
lr-x------. 1 root root 64 May 10 10:53 3 -> /proc/kmsg
l-wx------. 1 root root 64 May 10 10:53 4 -> /var/log/messages
l-wx------. 1 root root 64 May 10 10:53 5 -> /var/log/cron

840 ? 00:00:00 sshd
[root@localhost fd]# cd /proc/840/fd
[root@localhost fd]# ll
total 0
lrwx------. 1 root root 64 May 10 10:53 0 -> /dev/null
lrwx------. 1 root root 64 May 10 10:53 1 -> /dev/null
lrwx------. 1 root root 64 May 10 10:53 2 -> /dev/null
lrwx------. 1 root root 64 May 10 10:53 3 -> socket:[10348]
lrwx------. 1 root root 64 May 10 10:53 4 -> socket:[10352]

因此,我们可以通过使用 ulimit -n 来限制程序所能打开的最大文件描述符数量,从而达到限制 socket 创建的数量。

使用 ulimit 限制 shell 多线程程序堆栈的大小(增加可用线程数量)
在最后一个例子中,向大家介绍如何使用 -s(单位 KB)来对线程的堆栈大小进行限制,从而减少整个多线程程序的内存使用,增加可用线程的数量。这个例子取自于一个真实的案例。
我们所遇到的问题是系统对我们的多线程程序有如下的限制:
# ulimit -v 200000
根据本文前面的介绍,这意味着我们的程序最多只能使用不到 200MB 的虚拟内存。由于我们的程序是一个多线程程序,程序在运行时会根据需要创建新的线程,
这势必会增加总的内存需求量。一开始我们对堆栈大小的限制是 1024 (本例子中使用 1232 来说明):
# ulimit -s 1232
当我们的程序启动后,通过 pmap 来查看其内存使用情况,可以看到多个占用 1232KB 的数据段,这些就是程序所创建的线程所使用的堆栈:
# pmap -x pid
每当一个新的线程被创建时都需要新分配一段大小为 1232KB 的内存空间,而我们总的虚拟内存限制是 200MB,所以如果我们需要创建更多的线程,那么一个可以改进的方法就是减少每个线程的固定堆栈大小,
这可以通过 ulimit -s 来实现:
# ulimit -s 512
我们将堆栈大小设置为 512KB,这时再通过 pmap 查看一下我们的设置是否起作用:
# pmap -x pid
从上面的信息可以看出,我们已经成功的将线程的堆栈大小改为 512KB 了,这样在总内存使用限制不变的情况下,我们可以通过本小节介绍的方法来增加可以创建的线程数,从而达到改善程序的多线程性能。

综上所述,linux 系统中的 ulimit 指令,对资源限制和系统性能优化提供了一条便捷的途径。从用户的 shell 启动脚本,应用程序启动脚本,以及直接在控制台,
都可以通过该指令限制系统资源的使用,包括所创建的内核文件的大小、进程数据块的大小、Shell 进程创建文件的大小、内存锁住的大小、常驻内存集的大小、打开文件描述符的数量、
分配堆栈的最大大小、CPU 时间、单个用户的最大线程数、Shell 进程所能使用的最大虚拟内存,等等方面。本文中的示例非常直观的说明了 ulimit 的使用及其产生的效果,
显而易见,ulimit 对我们在 Linux 平台的应用和开发工作是非常实用的。

840 ? 00:00:00 sshd
[root@localhost fd]# pmap -x 840

[root@localhost ~]# ulimit -a 显示所有已设值

修改/etc/profile文件,加入:
  ulimit -u 10240
  ulimit -n 4096
  ulimit -d unlimited
  ulimit -m unlimited
  ulimit -s unlimited
  ulimit -t unlimited
  ulimit -v unlimited

永久性改变
解除 Linux 系统的最大进程数和最大文件打开数限制:
vi /etc/security/limits.conf
# 添加如下的行
* soft noproc 11000 #软连接
* hard noproc 11000 #硬连接
* soft nofile 4100
* hard nofile 4100
说明:* 代表针对所有用户,noproc 是代表最大进程数,nofile 是代表最大文件打开数

-bash:fork:Resource temporarily unavailable的问题
出现这个问题的原因是linux用户的连接数设置的太小,只要修改max user processes就可以

open files                      (-n) 65536需要修改 (因为是tcp协议  要打开套接字,要打开文件句柄,而单进程的最大打开文件句柄操作系统是有限制的,默认是1024)

最近在Linux服务器上发布应用时碰到一个如下的异常:
Caused by: java.lang.OutOfMemoryError: unable to create new native thread
at java.lang.Thread.start0(Native Method)
at java.lang.Thread.start(Thread.java:640)

初看可能会认为是系统的内存不足,如果这样想的话就被这段提示带到沟里面去了。
上面这段错误提示的本质是Linux操作系统无法创建更多进程,导致出错。因此要解决这个问题需要修改Linux允许创建更多的进程。

正确的做法是修改/etc/security/limit.conf文件或limits.d目录中添加相应的限制,而非什么都往/etc/profile里添加

当前session临时生效,重新登录失效
ulimit -u    先查看
ulimit -u 10240 再修改
ulimit -u与ulimit -a都可以查看
    
修改/etc/security/limits.d/90-nproc.conf文件中的值,永久生效

不管是在limit.conf里还是90-nproc.conf里
如果都不设置默认显示3788
如果要设置要用hard,用soft好像没有效果。
*    soft    nproc    4096

下面的两篇文章非常重要,对认识ulimit,网上其它文章都没有太大价值,全一样。

http://coolnull.com/2800.html

http://blog.yufeng.info/archives/2568

转载于:https://www.cnblogs.com/createyuan/p/3720263.html

linux包之bash之内置命令ulimit相关推荐

  1. linux包之procps之sysctl命令

    概述 [root@localhost ~]# rpm -qf /sbin/sysctl procps-3.2.8-25.el6.x86_64 我们常常在 Linux 的 /proc/sys 目录下,手 ...

  2. #linux包之sysstat之iostat命令

    概述 对于I/O-bond类型的进程,我们经常用iostat工具查看进程IO请求下发的数量.系统处理IO请求的耗时,进而分析进程与操作系统的交互过程中IO方面是否存在瓶颈. 同vmstat一样,ios ...

  3. linux包之iproute之ip命令

    [root@localhost ~]# rpm -qf /sbin/ip iproute-2.6.32-31.el6.x86_64 ip 是个命令, ip 命令的功能很多!基本上它整合了 ifconf ...

  4. fooview辅助功能 shell_列出所有Bash Shell内置命令的方法示例

    前言 Shell有很多内置在其源代码中的命令.这些命令是内置的,所以Shell不必到磁盘上搜索它们,执行速度因此加快.不同的Shell内置命令有所不同. 内置命令包含在 bash shell 本身里面 ...

  5. linux sh 帮助,技术|获取有关 Linux shell 内置命令的帮助

    Linux 内置命令属于用户 shell 的一部分,本文将告诉你如何识别它们并获取使用它们的帮助. Linux 内置命令是内置于 shell 中的命令,很像内置于墙中的书架.与标准 Linux 命令存 ...

  6. 最全的Linux运维bash脚本常见用法总结

    删除重复的数组元素 创建临时关联数组.设置关联数组 值并发生重复赋值时,bash会覆盖该键.这 允许我们有效地删除数组重复. CAVEAT:需要bash4+ 示例功能: remove_array_du ...

  7. linux内核与bash脚本接囗,Bash脚本编程之脚本基础和bash配置文件

    脚本基础 不严谨地说,编程语言根据代码运行的方式,可以分为两种方式: 编译运行:需要先将人类可识别的代码文件编译成机器可运行的二进制程序文件后,方可运行.例如C语言和Java语言. 解释运行:需要一个 ...

  8. 14.Linux rpm,brew软件安装包命令,zsh和bash,内置命令和外部命令,ps命令,top命令解析,swp,为什么cpu利用率很低,负载却很高?

    解释一下rpm, opt,opt-get, brew,brewhome rpm,apt,apt-get,brew,和homebrew都是与软件包管理有关的术语.它们分别用于不同的操作系统. rpm是一 ...

  9. Linux查看内置命令和非内置命令帮助的几种方法(man、help、info)

    内置命令就是shell内核自带的,因为shell当中自己要进行管理,那么就需要一些命令进行管理,不同的shell肯定有不同的shell命令,我们用type命令就可以看到其的类型,内置shell命令其实 ...

最新文章

  1. angular初步认识一
  2. linux软件安装不完全傻瓜手册
  3. 60岁代码匠的几篇小作文,解决了大多数程序的迷茫(下)
  4. linux 学习过程中的坑之 find 正则表达式
  5. 第十五届全国大学生智能汽车竞赛创意组比赛进入全国总决赛队伍名单
  6. struts2常见报错
  7. dict去重python_python去重,一个由dict组成的list的去重示例
  8. java项目使用junit_在Java 8之前的项目中使用JUnit 5
  9. Gradle入门:我们的第一个Java项目
  10. 5G大幕已启 将如何改变社会?
  11. linux查看CPU高速缓存(cache)信息
  12. 云存储安全,主要面临哪些问题
  13. angelhack_我的团队如何撼动AngelHack Seattle Hackathon
  14. ImageView 加载本地(手机)图片
  15. HDU - 6070 Dirt Ratio (二分 + 线段树)
  16. C#的AES加密解密(ECB)
  17. Neos Flow ActionController 返回JSON
  18. Integer类型的比较
  19. 奔跑吧兄弟一起学平面UI设计培训
  20. OpenGL(12)GL库API

热门文章

  1. UFLDL 教程学习笔记(二)反向传导算法
  2. 离线在远程linux服务器配置vscode-python环境以及在容器中配置
  3. visual studio 删除附加项
  4. java 并发queue_深入浅出 Java Concurrency (19): 并发容器 part 4 并发队列与Queue简介
  5. php c 交互,C语言和go语言之间的交互操作方法
  6. python命令符bash_从python结构执行远程bash命令时“转义”$
  7. linux ipv4参数查看,Linux内核参数之IPV4变量引用
  8. c语言加粗字体怎么弄,excel表格如何批量加粗文字
  9. java核心面试_前100多个核心Java面试问题
  10. Java ArrayList的Array,Array的ArrayList