问题背景,查错过程
背景就是同事在linux上启动一个java程序,立刻失败,并产生一个hs_err_pidxxxxx.log。看了下这个log日志,报错的原因是Out of memorry…
#
# There is insufficient memory for the Java Runtime Environment to continue.
# Cannot create GC thread. Out of system resources.
# Possible reasons:
# The system is out of physical RAM or swap space
# In 32 bit mode, the process size limit was hit
# Possible solutions:
# Reduce memory load on the system
# Increase physical memory or swap space
# Check if swap backing store is full
# Use 64 bit Java on a 64 bit OS
# Decrease Java heap size (-Xmx/-Xms)
# Decrease number of Java threads
# Decrease Java thread stack sizes (-Xss)
# Set larger code cache with -XX:ReservedCodeCacheSize=
- top查看机器的内存使用情况
top
#发现内存还有很多,并没有占满。
- 查看操作系统版本(报错里有提示jdk是否为64位,运行在64位操作系统下)
uname -a
- 查看jdk版本
java -version
该命令居然也报内存溢出问题
到这里我的第一直觉就是ulimit的原因,劈里啪啦一顿设置,立马搞定。因为之前也有过因为ulimit导致主机不能登录,java程序内存溢出以及报open files太多的情况,当时被这个折腾了好久。所以记忆犹新,这里记录分享一下如何设置ulimit
Ulimit设置(需要root用户操作)
- 查看当前ulimit资源限制情况
ulimit -a
结果如下:
core file size (blocks, -c) 0
data seg size (kbytes, -d) unlimited
scheduling priority (-e) 0
file size (blocks, -f) unlimited
pending signals (-i) 578038
max locked memory (kbytes, -l) 64
max memory size (kbytes, -m) unlimited
open files (-n) 1024
pipe size (512 bytes, -p) 8
POSIX message queues (bytes, -q) 819200
real-time priority (-r) 0
stack size (kbytes, -s) 10240
cpu time (seconds, -t) unlimited
max user processes (-u) 578038
virtual memory (kbytes, -v) unlimited
file locks (-x) unlimited
- 可以发现open files等参数比较小(默认1024),接下来修改限制(参考一下命令及最终结果修改)
vi /etc/security/limits.conf
* soft nofile 32768
* hard nofile 65536
vi /etc/security/limits.d/90-nproc.conf
* soft nproc 10240
root soft nproc unlimited
- 修改完无需重启,用户重新登录即可。如果又不想重新登录,可以在会话里设置一下:
ulimit -n 10240
这个值不能超过ulimit -a里面的设置,所以必须要root修改完才能调大
PS: 已经启动的程序 需要 在生效的会话(也即重新登录且生效或手动设置ulimit值的会话)下,再重启才能生效。
如何查看程序的ulimit,可以使用:
## 其中{PID}替换为进程ID
cat /proc/{PID}/limits
----以下为命令执行结果参考,仅列举了几行
Limit Soft Limit Hard Limit Units
Max cpu time unlimited unlimited seconds
Max file size unlimited unlimited bytes
Max data size unlimited unlimited bytes
Max open files 65535 65535 files
后记
在其他主机上如上设置后,重新登录并不能生效。可以尝试如下方法,但切记尝试前,先多开一些会话窗口,或者临时开启telnet登录。
因为要修改ssh配置,以及重启sshd服务,可能会导致新会话登录失败的问题。
由于ssh 版本或者linux版本原因,有以下两个方法可以尝试:
- 修改/etc/ssh/sshd_config的UseLogin no为UseLogin yes ,并重启sshd服务即可 。
(优选 ),但同时必须保证“UsePAM no”配置项处于注释状态,也即“#UsePAM no” - 修改/etc/ssh/sshd_config的UsePAM no为UsePAM yes,并重启sshd服务
(慎用),修改此配置并重启sshd服务后,可能会导致ssh登录失败(提示密码错误);
很奇怪的事,有时候以上两种单独设都不生效。两项都开启时(也即UsePAM yes + UseLogin yes),重启sshd后,会提示密码错误。这时再把以上两项还原(也即相当于重来没有改动过),再重启sshd后,ulimit都正常了~遇到过多次这样,尚不明白原因。
重启完sshd服务后,一定要记得新开个会话验证是否能登录进入。如果不能,将配置还原,再重启sshd服务。