Java EE应用程序在Glassfish上的性能调优案例分析 - 编程入门网
塞了那些有数据库操作的请求,占用了所有数据库连接池中的连接。后续的请求如果还要从连接池中获取连接,就会阻塞在连接池上。当解决数据库死锁的问题之后,性能问题迎刃而解。
Java EE应用程序在Glassfish上的性能调优案例分析(2)时间:2010-12-25 BlogJava kit_lo大对象缓存问题 电信应用运行在64位Java虚拟机上,系统运行得很不稳定,系统经常停止响应。使用进程工具查看,发现进程并没有被杀死或挂起。利用Java虚拟机的工具发现系统在长时间的进行内存回收,内存回收的时间长达15分钟,整个系统在内存回收的时候就像挂起一样。另外还观察到系统使用了12G的内存(因为是 64位虚拟机所以突破了4G内存的限制)。从开发人员那里了解到,这个应用为了提高性能,大量使用了对象缓存,但是事与愿违,在Java中使用过多的内存,虽然在正常运行的时候能够获得很好的性能,但是会大大增加内存回收的时间。特别是对象缓存,本系统使用了8G的缓存空间,共缓存了6000多万个对象,对这些对象的遍历导致了长时间的内存回收。根据我们的建议,将缓存空间减少到1G,并调整回收算法(使用增量回收的算法),使得系统由于内存回收而造成的最大停顿时间减少到4秒,基本满足用户的需求。 外部命令问题 数字校园应用运行在4CPU的Solaris10服务器上,中间件为JavaEE服务器。系统在做大并发压力测试的时候,请求响应时间比较慢,通过操作系统的工具(mpstat)发现CPU使用率比较高。并且系统占用绝大多数的CPU资源而不是应用本身。这是个不正常的现象,通常情况下用户应用的CPU占用率应该占主要地位,才能说明系统是正常工作。通过Solaris 10的Dtrace脚本,我们查看当前情况下哪些系统调用花费了最多的CPU资源,竟然发现最花费CPU的系统调用是“fork”。众所周知, “fork”系统调用是用来产生新的进程,在Java虚拟机中只有线程的概念,绝不会有进程的产生。这是个非常异常的现象。通过本系统的开发人员,我们找到了答案:每个用户请求的处理都包含执行一个外部shell脚本,来获得系统的一些信息。这是通过Java的“Runtime.getRuntime ().exec”来完成的,但是这种方法在Java中非常消耗资源。Java虚拟机执行这个命令的方式是:首先克隆一个和当前虚拟机一样的进程,再用这个新的进程去执行外部命令,最后再退出这个进程。如果频繁执行这个操作,系统的消耗会很大,不仅在CPU,内存操作也很重。用户根据建议去掉这个shell 脚本执行的语句,系统立刻回复了正常。 文件操作问题 内容管理(CMS)系统运行在JavaEE服务器上,当系统长时间运行以后,性能非常差,用户请求的延时比系统刚上线的时候要大很多,并且用户的并发量很小,甚至是单个用户也很慢。通过操作系统的工具观察,一切都很正常,CPU利用率不高,IO也不是很大,内存很富余,网络几乎没有压力(因为并发用户少)。先不考虑线程互锁的问题,因为单个用户性能也不好。通过Java虚拟机观察也没有发现什么问题(内存回收很少发生)。这使得我们不得不使用代码跟踪器来全程跟踪代码。我们采用了Netbeans的Profiler,跟踪的结果非常意外,用户请求的90%的时间在创建新文件。从系统设计人员了解到,此系统使用了一个目录用于保存所有上传和共享的文件,文件用其命名方式来唯一区别于其他文件。我们查看了那个文件目录,发现该目录下已经拥有80万个文件了。这时候我们才定位到问题了:在同个目录下放置太多的文件,在创建新文件的时候,系统的开销是比较大的,例如为了防止重名,文件系统会遍历当前目录下所有的文件名等等。根据我们的建议,将文件分类保存在不同的目录下,性能有了大幅度的提高。 高速缓存命中率问题 运行在JavaEE服务器上的ERP系统,在 |
凌众科技专业提供服务器租用、服务器托管、企业邮局、虚拟主机等服务,公司网站:http://www.lingzhong.cn 为了给广大客户了解更多的技术信息,本技术文章收集来源于网络,凌众科技尊重文章作者的版权,如果有涉及你的版权有必要删除你的文章,请和我们联系。以上信息与文章正文是不可分割的一部分,如果您要转载本文章,请保留以上信息,谢谢! |