外部命令导致系统缓慢(四)

1、案例介绍

运行在一台4个CPU的Solaris 10操作系统上,中间件GlassFish服务器,系统在做大并发压力测试的时候,发现请求响应时间比较慢,通过操作系统的mystat工具发现CPU使用率很高,并且系统占用绝大多数的CPU资源的程序并不是应用系统本身,这是一个不正常的现象,通常情况下用户应用的CPU占用率应该占主导第五位,才能说明系统工作正常

2、查看出问题的地方

通过Solaris 10的Dtrace脚本可以查看当前情况下哪些系统调用花费了最多的CPU资源,
Dtrace 运行后发现最消耗CPU资源的竟然是"fork"系统调用,"fork"系统调用是Linux用来产生新进程的,而在java虚拟机中,用户编写java代码最多只有线程的概念,不应当有进程的产生

3、怎么出现的这个问题

每个用户请求的处理都需要执行一个外部的shell脚本来获取系统的一些信息,执行这个shell脚本是通过java的Runtime.getRuntime().exec()方法来实现的,虽然这个调用可以达到目的,但是它在java虚拟机中是非常耗费资源的操作,即使外部命令很快执行完成,那频繁调用时创建进程的开销也非常大

可能你会有疑惑为什么它会创建一个新进程而且开销很大,下面解释一下:
当当前下项目需要调用外部的命令脚本语言来实现功能,Jdk中提供了Runtime.getRuntime().exec()方法来执行,
java虚拟机执行过程:首先克隆一个和当前虚拟机拥有一样环境变量的进程(这时候Linux中的fork来创建的新进程),再用这个新的进程去执行外部命令,最后再退出这个进程,
如果频繁执行这个操作,系统的开销会很大,不仅CPU,内存负担也会很大

4、怎么解决这个问题

去掉这个Shell脚本执行的语句,改为使用Java API去获取这些信息,这样就不用克隆一个新的进程了,系统恢复了正常。

5、总结

虽然java的Runtime.getRuntime().exec()方法可以调用外部的脚本语言,但是如果项目中频繁调用此(要考虑频繁创建进程的问题),请考虑转换成Java API的方式执行

发布了213 篇原创文章 · 获赞 22 · 访问量 6万+

猜你喜欢

转载自blog.csdn.net/weixin_43113679/article/details/100801842
今日推荐