jvm的调优
首先我们要知道jvm的调优,主要是对那些部分的优化。通过jvm内存模型我们可以,首先是分析遇到的问题,然后通过一些工具或者手段找到问题所在,然后通过一定的措施解决问题,下面我们也将按着这个思路来给出具体的操作。
问题分析
这个主要是根据我们在运行程序时出现的问题:内存溢出,栈溢出,或者请求停顿。
解决方案
堆内存溢出的话我们首先看jvm的配置参数:
- java -Xmx3550m -Xms3550m -Xss128k -XX:NewRatio=4 -XX:SurvivorRatio=4 -XX:MaxPermSize=16m -XX:MaxTenuringThreshold=0
-Xmx3550m:设置JVM最大可用内存为3550M。
-Xms3550m:设置JVM促使内存为3550m。此值可以设置与-Xmx相同,以避免每次垃圾回收完成后JVM重新分配内存。
-Xmn2g:设置年轻代大小为2G。整个堆大小=年轻代大小 + 年老代大小 + 持久代大小。持久代一般固定大小为64m,所以增大年轻代后,将会减小年老代大小。此值对系统性能影响较大,Sun官方推荐配置为整个堆的3/8。
-Xss128k:设置每个线程的堆栈大小。JDK5.0以后每个线程堆栈大小为1M,以前每个线程堆栈大小为256K。更具应用的线程所需内存大小进行调整。在相同物理内存下,减小这个值能生成更多的线程。但是操作系统对一个进程内的线程数还是有限制的,不能无限生成,经验值在3000~5000左右。
-XX:NewRatio=4:设置年轻代(包括Eden和两个Survivor区)与年老代的比值(除去持久代)。设置为4,则年轻代与年老代所占比值为1:4,年轻代占整个堆栈的1/5。但是如果设置了年轻代的大小和最大最小对内存,这个值就没有必要设置了。
-XX:SurvivorRatio=4:设置年轻代中Eden区与Survivor区的大小比值。设置为4,则两个Survivor区与一个Eden区的比值为2:4,一个Survivor区占整个年轻代的1/6.一般默认比值为2/8
-XX:MaxPermSize=64m:设置永久代大小为64m。一般设置为物理内存的1/64。(这个可以看着做事方法区的大小,在HotSpot虚拟机中方法去和永久带是一个概念)
-XX:MaxTenuringThreshold=0:设置垃圾最大年龄。如果设置为0的话,则年轻代对象不经过Survivor区,直接进入年老代。对于年老代比较多的应用,可以提高效率。如果将此值设置为一个较大值,则年轻代对象会在Survivor区进行多次复制,这样可以增加对象再年轻代的存活时间,增加在年轻代即被回收的概论。
栈溢出
主要有栈溢出两种情景:
- 线程请求的栈的深度大于虚拟机所允许的最大深度,将抛出StackOverflowError
栈的深度和设置的-xss的大小以及和局部变量的数量以及大小有关,-xss越小,局部变量个数越多长度越长,深度就越小。栈帧存放着局部变量,方法返回值,这些值越多,或者值越大,那么战阵就越大,占用的内存就越大,栈的深度就越小。
- 虚拟机在扩展栈时无法申请到足够的空间,将抛出OutOfMemoryError
栈的大小(虚拟机栈和本地方法栈瓜分的大小)=系统限制的内存的大小-最大堆内存的大小(Xmx)-最大方法区内存(MaxPermSize)-程序计数器(很小)-虚拟机本身耗费的内存(很小)
方法区溢出
常量池内存溢出:运行时常量池也属于方法区
其他方法区内存溢出:主要是存放class相关信息的地方。主要是大量使用cglib技术,增强类越多,就需要越大的方法区内存。
使用到的工具
- jstack:java堆栈跟踪工具
此工具是查看某个进程下的当前时刻线程的状态信息的,生成虚拟机当前时刻的线程快照,线程快照就是当前虚拟机中每一条线程正在执行的方法堆栈的集合,主要目的是定位线程长时间停顿的原因。
命令格式:
jstack [ option ] pid
基本参数:
-F 当'jstack [-l] pid'没有相应的时候强制打印栈信息
-l 长列表. 打印关于锁的附加信息,例如属于java.util.concurrent的ownable synchronizers列表.
-m 打印java和native c/c++框架的所有栈信息. -h | -help打印帮助信息
pid 需要被打印配置信息的java进程id,可以用jps工具查询
重点关注的线程状态:
死锁, Deadlock(重点关注)
执行中,Runnable
等待资源, Waiting on condition(重点关注)
等待获取监视器, Waiting on monitor entry(重点关注)
暂停,Suspended
对象等待中,Object.wait() 或 TIMED_WAITING
阻塞, Blocked(重点关注)
停止,Parked
线程状态解析
Deadlock:死锁线程,一般指多个线程调用间,进入相互资源占用,导致一直等待无法释放的情况。
Runnable:一般指该线程正在执行状态中,该线程占用了资源,正在处理某个请求,有可能正在传递SQL到数据库执行,有可能在对某个文件操作,有可能进行数据类型等转换。
Waiting on condition:
该状态出现在线程等待某个条件的发生。具体是什么原因,可以结合 stacktrace来分析。最常见的情况是线程在等待网络的读写,
比如当网络数据没有准备好读时,线程处于这种等待状态,而一旦有数据准备好读之后,线程会重新激活,读取并处理数据。在 Java引入 NewIO之前,对于每个网络连接,
都有一个对应的线程来处理网络的读写操作,即使没有可读写的数据,线程仍然阻塞在读写操作上,这样有可能造成资源浪费,而且给操作系统的线程调度也带来压力。
在 NewIO里采用了新的机制,编写的服务器程序的性能和可扩展性都得到提高。
如果发现有大量的线程都在处在 Wait on condition,从线程 stack看, 正等待网络读写,这可能是一个网络瓶颈的征兆。因为网络阻塞导致线程无法执行。
一种情况是网络非常忙,几 乎消耗了所有的带宽,仍然有大量数据等待网络读 写;另一种情况也可能是网络空闲,但由于路由等问题,导致包无法正常的到达。
所以要结合系统的一些性能观察工具来综合分析,比如 netstat统计单位时间的发送包的数目,如果很明显超过了所在网络带宽的限制 ; 观察 cpu的利用率,如果系统态的 CPU时间,
相对于用户态的 CPU时间比例较高;如果程序运行在 Solaris 10平台上,可以用 dtrace工具看系统调用的情况,如果观察到 read/write的系统调用的次数或者运行时间遥遥领先;
这些都指向由于网络带宽所限导致的网络瓶颈。另外一种出现 Wait on condition的常见情况是该线程在 sleep,等待 sleep的时间到了时候,将被唤醒。
blocked:线程阻塞,是指当前线程执行过程中,所需要的资源长时间等待却一直未能获取到,被容器的线程管理器标识为阻塞状态,可以理解为等待资源超时的线程。
Waiting for monitor entry 和 in Object.wait():Monitor是 Java中用以实现线程之间的互斥与协作的主要手段,它可以看成是对象或者 Class的锁。每一个对象都有,也仅有一个 monitor。
jstack报告分析
- jstat:虚拟机统计信息监视工具
主要显示虚拟机进程中的类装载,内存,垃圾收集,jit编译等运行时的数据,是定位云定期虚拟机问题的首选工具
命令格式:
jstat -<option> [-t] [-h<lines>] <vmid> [<interva[s|ms]> [<count>]]
参数解释:
Options — 选项,我们一般使用 -gcutil 查看gc情况
vmid — VM的进程号,即当前运行的java进程号
interval[s|ms] —— 间隔时间,单位为秒或者毫秒,默认为ms。必须是正整型。
count — 打印次数,如果缺省则打印无数次
选项参数
jstat工具特别强大,有众多的可选项,详细查看堆内各个部分的使用量,以及加载类的数量。使用时,需加上查看进程的进程id,和所选参数。以下详细介绍各个参数的意义。
jstat -class pid:显示加载class的数量,及所占空间等信息。
jstat -compiler pid:显示VM实时编译的数量等信息。
jstat -gc pid:可以显示gc的信息,查看gc的次数,及时间。其中最后五项,分别是young gc的次数,young gc的时间,full gc的次数,full gc的时间,gc的总时间。
jstat -gccapacity:可以显示,VM内存中三代(young,old,perm)对象的使用和占用大小,如:PGCMN显示的是最小perm的内存使用量,PGCMX显示的是perm的内存最大使用量,PGC是当前新生成的perm内存占用量,PC是但前perm内存占用量。其他的可以根据这个类推, OC是old内纯的占用量。
jstat -gcnew pid:new对象的信息。
jstat -gcnewcapacity pid:new对象的信息及其占用量。
jstat -gcold pid:old对象的信息。
jstat -gcoldcapacity pid:old对象的信息及其占用量。
jstat -gcpermcapacity pid: perm对象的信息及其占用量。
jstat -gcutil pid:统计gc信息统计。
jstat -printcompilation pid:当前VM执行的信息。
- jmap:java内存映像工具
主要是用于生成堆转存快照。
命令行格式:
jmap [option] LVMID(LVMID指的是进程ID)
option参数:
- dump : 生成堆转储快照,可以再windows下使用
- finalizerinfo : 显示在F-Queue队列等待Finalizer线程执行finalizer方法的对象,不可以再windows下使用
- heap : 显示Java堆详细信息,不可以再windows下使用
- histo : 显示堆中对象的统计信息,包括类,实例数量,合计荣力量。可以再windows下使用
- permstat : to print permanent generation statistics,不可以再windows下使用
- F : 当-dump没有响应时,强制生成dump快照,不可以再windows下使用
- jinfo
- jps
- jhat
可视化工具
- jconsole
- visualVM
jvm的调优的更多相关文章
- JVM性能调优监控工具jps、jstack、jmap、jhat、jstat、hprof使用详解
摘要: JDK本身提供了很多方便的JVM性能调优监控工具,除了集成式的VisualVM和jConsole外,还有jps.jstack.jmap.jhat.jstat.hprof等小巧的工具,本博客希望 ...
- JVM性能调优监控工具jps、jstack、jmap、jhat、jstat使用详解(转VIII)
JVM本身就是一个java进程,一个java程序运行在一个jvm进程中.多个java程序同时运行就会有多个jvm进程.一个jvm进程有多个线程至少有一个gc线程和一个用户线程. JDK本身提供了很多方 ...
- JVM参数调优
JVM参数调优 JVM参数调优是一个很头痛的问题,可能和应用有关系,下面是本人一些调优的实践经验,希望对读者能有帮助,环境LinuxAS4,resin2.1.17,JDK6.0,2CPU,4G内存,d ...
- Java性能优化权威指南-读书笔记(二)-JVM性能调优-概述
概述:JVM性能调优没有一个非常固定的设置,比如堆大小设置多少,老年代设置多少.而是要根据实际的应用程序的系统需求,实际的活跃内存等确定.正文: JVM调优工作流程 整个调优过程是不断重复的一个迭代, ...
- JVM性能调优
摘自:http://uule.iteye.com/blog/2114697 JVM垃圾回收与性能调优总结 JVM调优的几种策略 一.JVM内存模型及垃圾收集算法 1.根据Java虚拟机规范,JVM将 ...
- JVM 性能调优实战之:一次系统性能瓶颈的寻找过程
玩过性能优化的朋友都清楚,性能优化的关键并不在于怎么进行优化,而在于怎么找到当前系统的性能瓶颈.性能优化分为好几个层次,比如系统层次.算法层次.代码层次…JVM 的性能优化被认为是底层优化,门槛较高, ...
- JVM 性能调优实战之:使用阿里开源工具 TProfiler 在海量业务代码中精确定位性能代码
本文是<JVM 性能调优实战之:一次系统性能瓶颈的寻找过程> 的后续篇,该篇介绍了如何使用 JDK 自身提供的工具进行 JVM 调优将 TPS 由 2.5 提升到 20 (提升了 7 倍) ...
- (转)JVM参数调优八大技巧
这里和大家分享一下JVM参数调优的八条经验,JVM参数调优,这是很头痛的问题,设置的不好,JVM不断执行FullGC,导致整个系统变得很慢,网站停滞时间能达10秒以上,相信通过本文的学习你对JVM参数 ...
- JVM的GC机制及JVM的调优方法
内存管理和垃圾回收是JVM非常关键的点,对Java性能的剖析而言,了解内存管理和垃圾回收的基本策略非常重要. 1.在程序运行过程当中,会创建大量的对象,这些对象,大部分是短周期的对象,小部分是长周期的 ...
- jvm 性能调优
[转载]:http://blog.csdn.net/chen77716/article/details/5695893 最近因项目存在内存泄漏,故进行大规模的JVM性能调优 , 现把经验做一记录. 一 ...
随机推荐
- Java编程的逻辑 (79) - 方便的CompletionService
本系列文章经补充和完善,已修订整理成书<Java编程的逻辑>,由机械工业出版社华章分社出版,于2018年1月上市热销,读者好评如潮!各大网店和书店有售,欢迎购买,京东自营链接:http: ...
- mac通过路径找到对应的文件夹
在finder中 command + shift + G 跳出窗口中输入指定的路径,即可到达.
- AndroidStudio 代码(导入类)报错但可正常运行,以及解决此问题后带来的系列问题解决
首先是应用中很多导入的类都报红色异常显示找不到此类,但运行编译正常: 第一种方法: 点击AndroidStudio菜单File -> Invalidate Caches/Restar… ,在弹出 ...
- EventBus vs Otto vs Guava--自定义消息总线
同步发表于http://avenwu.net/ioc/2015/01/29/custom_eventbus Fork on github https://github.com/avenwu/suppo ...
- tensorflow模型量化
tensorflow模型量化/DATA/share/DeepLearning/code/tensorflow/bazel-bin/tensorflow/tools/graph_transforms/t ...
- Intellij IDEA 2015 导入MyEClipse工程
一.步骤说明 File->New->Projet from existing sources,选择要导入的项目,并且导入项目; 打开 “open module settings”进行设置: ...
- 安卓开发笔记——丰富多彩的TextView
随手笔记,记录一些东西~ 记得之前写过一篇文章<安卓开发笔记——个性化TextView(新浪微博)>:http://www.cnblogs.com/lichenwei/p/4411607. ...
- nginx-启动gzip、虚拟主机、请求转发、负载均衡
一.启用gzip 1 gzip on; 2 gzip_min_length 1k; 3 gzip_buffers 4 16k; 4 gzip_http_version ...
- 在MyEclipse中将Java Project转换成Web Project
在MyEclipse中将Java Project转换成Web Project 此添加方法是针对MyEclipse中添加的: 编辑工程的.project文件: 添加 <nature>com. ...
- 重定向android log
android里面的log输出以往都是在eclipse里面看,如果通过USB连接电脑,可以输出到PC上. try { //adb logcat -v threadtime > logcat.tx ...