java性能调优

来源:互联网 发布:淘宝客服主要做什么 编辑:程序博客网 时间:2024/06/01 22:27

几个技术关键词:jvm内存、线程、nio

工具:jconsole、jvisualvm、eclipse的内存泄露分析工具MemoryAnalyzer

MemoryAnalyzer和jvisualvm功能有重叠,但是比jvisualvm要强大,大对象分析很有用,内存泄露可以甚至可以直接看到哪个对象过大,比如jmeter webscket插件测试过程中,发现一个类中stringbuffer过大,查找代码发现,其中没有对象中的stringbuffer在websocket连接断开之前不断append,导致内存无法回收。

jconsole非常实用,jvm参数,jvm内存占用情况、线程数、cpu非常直观,还可以通过jmx直接观察应用内部参数细节

说道性能调优其实很大一部分都会涉及到内存泄露,通常现象是老年代内存不断增长,GC后仍然无法回收,可以把内存dump之后用MemoryAnalyzer仔细分析,也可以在运行过程中用jvisualvm实时观看,jvisualvm的实时属性还是很不错的

上面说的主要是jvm内部内存泄露问题,在nio中还有一部分是外部内存或者说直接内存泄露,即用native方法直接申请了内存,这时候jvm是无法回收的,这时候的java内存回收退化成了c++,需要手动释放,所以使用nio,比如netty,尤其要注意直接内存释放问题

通常来说一定数量的线程能够提升系统吞吐和性能,但是过多的线程却恰恰相反,因为上下文切换会浪费大量时间,而nio的出现则是对这种上下文切换的一种“改变”,确实起到了非常好的效果

另外jvm参数一定要设置,首先是GC算法选取,java默认是PS marksweep,即并行标记算法,这个算法虽然用了多线程,但是stop the world时间很长,同时是完全的stop

应该使用UseConcMarkSweepGC,并发标记清除算法,虽然不能完全不去stop,但是部分实现了变使用边清理的模式,是一种更优选择

另外,还应该设置jvm线程栈大小,通常系统默认都很大,java好像是1024k,如果线程很多,这部分还是很占内存的,但时间线程栈用不了那么多内存,可以设置为-Xss 256k

-Xmx最大堆内存 -Xms初始堆内存同样需要设置,为防止jvm申请内存耗费时间,通常令两者相等,但不是越大越好,如上所述,线程栈是需要内存的,但是这部分内存不包含在堆内存里,如果你把堆内存设置过大,会导致没有内存分配给栈空间,而java应用通常都是很多线程的

在linux上可以用jps查看当前java进程id,然后用jstack -l pid打印出当前线程运行栈,这部分内容中有线程运行状态,比如runnable、park,可以分析系统运行状态

总之,java各种工具和开放出的接口十分丰富,可以和方便的分析应用运行态各种问题

0 0
原创粉丝点击