通过 ulimit 改善系统性能

通过 ulimit 改善系统性能

转:

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

假设有这样一种情况,当一台 Linux 主机上同时登陆了 10 个人,在系统资源无限制的情况下,这 10 个用户同时打开了 500 个文档,而假设每个文档的大小有 10M,这时系统的内存资源就会受到巨大的挑战。

而实际应用的环境要比这种假设复杂的多,例如在一个嵌入式开发环境中,各方面的资源都是非常紧缺的,对于开启文件描述符的数量,分配堆栈的大小,CPU 时间,虚拟内存大小,等等,都有非常严格的要求。资源的合理限制和分配,不仅仅是保证系统可用性的必要条件,也与系统上软件运行的性能有着密不可分的联系。这时,ulimit 可以起到很大的作用,它是一种简单并且有效的实现资源限制的方式。

ulimit 用于限制 shell 启动进程所占用的资源,支持以下各种类型的限制:所创建的内核文件的大小、进程数据块的大小、Shell 进程创建文件的大小、内存锁住的大小、常驻内存集的大小、打开文件描述符的数量、分配堆栈的最大大小、CPU 时间、单个用户的最大线程数、Shell 进程所能使用的最大虚拟内存。同时,它支持硬资源和软资源的限制。

作为临时限制,ulimit 可以作用于通过使用其命令登录的 shell 会话,在会话终止时便结束限制,并不影响于其他 shell 会话。而对于长期的固定限制,ulimit 命令语句又可以被添加到由登录 shell 读取的文件中,作用于特定的 shell 用户。

请右键保存本地,放大看。

www.zeeklog.com  - 通过 ulimit 改善系统性能

ulimit -a 用来显示当前的各种用户进程限制。
Linux对于每个用户,系统限制其最大进程数。为提高性能,可以根据设备资源情况,设置各linux 用户的最大进程数,下面我把某linux用户的最大进程数设为10000个:
ulimit -u 10000
对于需要做许多 socket 连接并使它们处于打开状态的 Java 应用程序而言,最好通过使用 ulimit -n xx 修改每个进程可打开的文件数,缺省值是 1024。
ulimit -n 4096 将每个进程可以打开的文件数目加大到4096,缺省为1024
其他建议设置成无限制(unlimited)的一些重要设置是:
数据段长度:ulimit -d unlimited
最大内存大小:ulimit -m unlimited
堆栈大小:ulimit -s unlimited
CPU 时间:ulimit -t unlimited
虚拟内存:ulimit -v unlimited
  
暂时地,适用于通过 ulimit 命令登录 shell 会话期间。
永久地,通过将一个相应的 ulimit 语句添加到由登录 shell 读取的文件中, 即特定于 shell 的用户资源文件,如:

1)、解除 Linux 系统的最大进程数和最大文件打开数限制:
    vi /etc/security/limits.conf
    # 添加如下的行
    * soft noproc 11000
    * hard noproc 11000
    * soft nofile 4100
    * hard nofile 4100

    说明:* 代表针对所有用户
    noproc 是代表最大进程数
    nofile 是代表最大文件打开数
2)、让 SSH 接受 Login 程式的登入,方便在 ssh 客户端查看 ulimit -a 资源限制:
    a、vi /etc/ssh/sshd_config
       把 UserLogin 的值改为 yes,并把 # 注释去掉
    b、重启 sshd 服务:
       /etc/init.d/sshd restart
3)、修改所有 linux 用户的环境变量文件:
vi /etc/profile
ulimit -u 10000
ulimit -n 4096
ulimit -d unlimited
ulimit -m unlimited
ulimit -s unlimited
ulimit -t unlimited
ulimit -v unlimited

/**************************************

有时候在程序里面需要打开多个文件,进行分析,系统一般默认数量是1024,(用ulimit -a可以看到)对于正常使用是够了,但是对于程序来讲,就太少了。

修改2个文件。
1./etc/security/limits.conf
    vi /etc/security/limits.conf
    加上:
    * soft nofile 8192
    * hard nofile 20480
2./etc/pam.d/login
    session required /lib/security/pam_limits.so
**********
    另外确保/etc/pam.d/system-auth文件有下面内容
    session required /lib/security/$ISA/pam_limits.so
    这一行确保系统会执行这个限制。
***********
3.一般用户的.bash_profile
#ulimit -n 1024
重新登陆ok
-------------
对于solaris

其实在系统里面有这样一个命令ulimit,以下是ulimit -a执行的结果:

time(seconds) unlimited
file(blocks) unlimited
data(kbytes) unlimited
stack(kbytes) 8192
coredump(blocks) unlimited
nofiles(descriptors) 1024
memory(kbytes) unlimited
其中nofiles就是文件描述符的变量值,该值受rlim_fd_cur这个参数的影响,可以用ulimit -n number命令来修改。但不管怎么改,程序仍然不能突破fd=256的限制。在Solaris Tunable Parameters Reference Manua这本书里面能查到以下的资料:

A 32-bit program using standard I/O is limited to 256 file descriptors。
A 64-bit program using standard I/O can use up to 2 billion descriptors。
这也就是说32位的程序是没有办法突破这个限制的,只有64位的程序才能使用高达2亿个文件描述符,SUN的软硬件在很早以前就实现了64位的架构,现在唯一要解决的就是将程序编译成64位程序,为了生成64位程序,就必须要有64位的编译器(其实不是这样的),如果你去www.sunfreeware.com下载64位编译器gcc,网站上没有特别注明是64位的gcc,但是会有个意外的收获,就是该软件的说明里面注明了只要在用gcc编译的时候加上-m64的option就能生成64位程序了。

于是用gcc -m64去编译生成一个64位程序后,用ulimit -n 102400将number of fd设成很大的情况下,所有问题迎刃而解,再也不存在文件描述符不够用的情况。

在/etc/system文件设置rlimi_fc_max和rlim_fd_cur格式如下:

* set hard limit on file descriptors
set rlim_fd_max = 4096
* set soft limit on file descriptors
set rlim_fd_cur = 1024
命令ulimit使用格式如下:

usage: ulimit [ -HSacdfnstv ] [ limit ]
ulimit -a是显示各参数的设置值,ulimit -n是用来设置fd的最大值的。
*************************************************

修改文件描述符限制

Solaris有两个参数控制进程可打开的文件描述符:rlim_fd_max,rlim_fd_cur。前者修改是个硬设置,修改需要权限,后者是个软设置,用户可以limit或者setrlimit() 修改,该值最大不能超过前者。一般我们在/etc/system里修改这两个参数

set rlim_fd_max = 65535

set rlim_fd_cur = 65535

==========================

ulimit 用于shell启动进程所占用的资源。

可以使用该命令查看进程占用资源的情况。

使用方法:ulimit [-acdfHlmnpsStvw] [size]

-H 设置硬件资源限制.
-S 设置软件资源限制.
-a 显示当前所有的资源限制.
-c size:设置core文件的最大值.单位:blocks
-d size:设置数据段的最大值.单位:kbytes
-f size:设置创建文件的最大值.单位:blocks
-l size:设置在内存中锁定进程的最大值.单位:kbytes
-m size:设置可以使用的常驻内存的最大值.单位:kbytes
-n size:设置内核可以同时打开的文件描述符的最大值.单位:n
-p size:设置管道缓冲区的最大值.单位:kbytes
-s size:设置堆栈的最大值.单位:kbytes
-t size:设置CPU使用时间的最大上限.单位:seconds
-v size:设置虚拟内存的最大值.单位:kbytes 5
1]在RH8的环境文件/etc/profile中,我们可以看到系统是如何配置ulimit的:

#grep ulimit /etc/profile
ulimit -S -c 0 > /dev/null 2>&1    (输出重定向,正常输出和异常输出都忽略)

这条语句设置了对软件资源和对core文件大小的设置
2]如果我们想要对由shell创建的文件大小作些限制,如:

#ll h
-rw-r--r-- 1 lee lee 150062 7月 22 02:39 h
#ulimit -f 100 #设置创建文件的最大块(一块=512字节)
#cat h>newh
File size limit exceeded
#ll newh
-rw-r--r-- 1 lee lee 51200 11月 8 11:47 newh
文件h的大小是150062字节,而我们设定的创建文件的大小是512字节x100块=51200字节
当然系统就会根据你的设置生成了51200字节的newh文件.
3]可以像实例1]一样,把你要设置的ulimit放在/etc/profile这个环境文件中.
如果针对所有用户设置,可在/etc/security/limits.conf 设置.

Read more

【Julia入门】2.6 自定义复合数据类型——《Julia全栈工程师》

【Julia入门】2.6 自定义复合数据类型——《Julia全栈工程师》

【Julia入门】2.6 自定义复合数据类型——《Julia全栈工程师》 * Julia 自定义复合数据类型 引言 Julia是一种面向对象的编程语言,具有强大的动态类型和灵活的类型系统。除了内建的基本数据类型(如整数、浮点数、字符串等)外,Julia还支持自定义复合数据类型,允许用户根据具体需求创建自己的数据结构。本文将详细讲解如何在Julia中自定义复合数据类型,并探讨其在实际应用中的优势。 自定义结构体(Struct) 在Julia中,结构体是一种常用的自定义复合数据类型。结构体可以包含多个字段,每个字段可以是不同的数据类型。通过定义结构体,我们可以将相关的数据组织在一起,方便管理和操作。 下面是一个简单的例子,演示如何定义一个包含姓名和年龄的结构体: struct Person name::String age::Int end 在这个例子中,我们定义了一个名为Person的结构体,它包含两个字段:name和age。字段类型分别被指定为String和Int。定义结构体时,字段名后面使用双冒号::指定字段类型。 创建结构体实例时,需

By Ne0inhk
【Julia入门】3.4 可变个数参数与元组实参——《Julia全栈工程师》

【Julia入门】3.4 可变个数参数与元组实参——《Julia全栈工程师》

【Julia入门】3.4 可变个数参数与元组实参——《Julia全栈工程师》 * Julia可变个数参数与元组实参 在Julia编程语言中,可变个数参数(Variadic Arguments)和元组实参(Tuple Arguments)是处理函数参数时的两个重要概念。它们允许程序员在定义和调用函数时更加灵活,特别是在处理不确定数量的参数时。 可变个数参数 Julia支持在函数定义中使用可变个数参数,这允许函数接受任意数量的参数。在函数定义中,通过在参数名前面加上三个点(...)来表示可变个数参数。在函数体内部,这些参数被收集到一个元组中。 例如,下面是一个接受可变个数参数的函数定义: function sum_varargs(...) args = vararg_values(...) return sum(args) end 在这个例子中,sum_varargs函数接受任意数量的参数,并将它们收集到一个名为args的元组中。然后,使用sum函数对元组中的元素进行求和。 调用这个函数时,可以传入任意数量的参数: result1 = sum_

By Ne0inhk
【Julia入门】3.7 函数式编程——《Julia全栈工程师》

【Julia入门】3.7 函数式编程——《Julia全栈工程师》

【Julia入门】3.7 函数式编程——《Julia全栈工程师》 * * Julia函数式编程 引言 Julia是一种高级编程语言,旨在提供接近C和Fortran的性能,同时保持类似于Python和R的易用性。在Julia中,函数式编程是一种重要的编程范式,它强调使用函数和不可变数据来构建程序。本文将详细解析Julia中的函数式编程特性,包括高阶函数、匿名函数(lambda函数)、映射与过滤、以及递归等。 高阶函数 高阶函数是指可以接受其他函数作为参数,或者返回函数的函数。在Julia中,高阶函数非常普遍,它们为代码复用和抽象提供了强大的工具。 # 定义一个高阶函数,接受一个函数作为参数 function apply_function(f, x) return f(x) end # 定义一个简单的函数 function square(x) return x * x end # 使用高阶函数apply_function result = apply_function(square,

By Ne0inhk
【Julia入门】9.11.2 类型系统-自定义多项式类型——《Julia全栈工程师》

【Julia入门】9.11.2 类型系统-自定义多项式类型——《Julia全栈工程师》

【Julia入门】9.11.2 类型系统-自定义多项式类型——《Julia全栈工程师》 * * * Julia类型系统-自定义多项式类型 引言 Julia是一种灵活的动态类型语言,它同时也支持静态类型特性,这使得开发者可以在需要时获得更高的性能。Julia的类型系统允许我们定义自己的类型,并且可以对类型进行丰富的操作,包括类型注解、类型推断、类型转换等。本文将详细介绍如何在Julia中自定义一个多项式类型,并展示其使用方法和优势。 多项式类型的定义 在Julia中,我们可以使用struct关键字来定义一个新的类型。对于多项式类型,我们可以定义一个结构体,其中包含多项式的系数和次数。例如: struct Polynomial coefficients :: Vector{Float64} # 系数向量 degree :: Int # 最高次数 end 在这个定义中,Polynomial是一个新的类型,它有两个字段:coefficients和degree。coefficients是一个浮点数向量,用于存

By Ne0inhk