JVM性能调优

JVM调优

  • 无监控不调优:如果没有一个评价系统性能的手段,则调优没有意义,因为你改了参数以后测试不出来
  • Java虚拟机调优主要涉及堆内存的调整和垃圾收集的调整

Java内存区域划分

  • 方法区:在Java8以后叫做永久区,存放静态变量,class文件

JVM采用垃圾的收集算法

  • 分代算法
  • 新生代:对象生存时间一般都比较短,存活对象少,所以可以使用复制算法
  • 老年代:垃圾少 一般使用标记整理算法

JVM参数

  • -:标准参数,所有JVM都支持
  • -X:非标准,每个JVM实现都不同
  • -XX:不稳定参数,下一个版本可能取消

Java对象分配顺序

  • 栈上分配

    1. 线程私有小对象
    2. 无逃逸
    3. 支持标量替换
    4. 无需调整,用JVM默认的即可
    5. 逃逸是指在栈上方法中分配了一个对象,但是有一个方法外的引用指向这个对象,说明这个对象逃逸了
    6. 栈上分配默认进行逃逸分析,默认支持标量替换
  • 线程本地分配TLAB

    1. 占用eden,默认1%
    2. 多线程的时候不用竞争eden就可以申请空间,提高效率
    3. 小对象
    4. 无需调整
  • 如果发现自己是一个大对象,则到老年代去分配
  • 否则,去eden区分配

  • 说明:

    1. new出来一个对象时,如果该对象特别小,同时JVM如果开了栈上优化这一模式,则会优先在栈上分配(JVM在Server模式下默认是栈上优化),不往堆上分配
    2. 如果栈空间分配满了,会去找线程本地内存(Thread Local Allocation Buffer),线程本地内存像eden区请求分配内存
    3. 发现在线程本地内存分配不了,检查一下是不是大对象,如果是大对象则直接放到老年代中,不然直接放到eden
  • 栈空间在栈帧上面,只要方法一结束,栈帧就没了,所以不需要垃圾收集,会自动收集

  • volatile:每个线程运行时,会给每个线程分配线程本地内存

在Eclipse使用run configuration进行运行

  • 在运行程序时,进行JVM参数配置
  • 在配置中使用-表示不使用
  • -XX:-DoEscapeAnalysis:不做逃逸分析
  • -XX:-EliminateAllocation:不做标量替换 有了这项和不做逃逸分析就不会栈上分配了
  • -XX:-UseTLAB:不使用线程本地缓存
  • -XX:+PrintGC:打印垃圾收集信息
  • -XX:PrintGCdetails:打印垃圾收集详细信息
  • 这个配置相当于就会向Eden区分配

内存溢出

  • -XX:+HeapDumpOnOutOFMemoryError:内存溢出时把堆的信息dump出来
  • -XX:HeapDumpPath=D:\temp\jvm.dump:存放dump出来的堆信息的文件
  • -XX:+PrintGCDetails:打印GC详细的信息
  • -Xms10M:程序起始的时候给该程序分配的堆内存
  • -Xmx10M:可以给该程序分配的最大的堆内存
  • 调优时将初始分配的内存和最大内存保持一致
  • vixVM:检测虚拟机堆的信息,还有其他工具:JProfiler Jhat Jmap JConsole

如何调整栈递归调用的次数,栈溢出-StackOverFlow

  • Xss:这个值调的比较小,线程的并发数量就可以特别多;如果调的比较大,线程的递归调用就可以比较深

常用参数设置

堆设置
  • -Xms:初始堆的大小
  • -Xmx:最大堆的大小
  • -Xss:线程栈的大小
  • -XX:NewSize=n:设置年轻代的大小
  • - -XX:NewRatio=n:设置年轻代和年老代的比值,如3表示年轻代:年老代比值为1:3
  • -XX:SurvivorRatio=n:年轻代中Eden区和两个Survivor区的比值。注意Survivor有两个。如3表示Eden:Survivor=3:2
  • -XX:MaxPermSize=n:设置持久代的大小
收集器设置
  • -XX:+UserSerialGC:设置串行收集器
  • -XX:+UserParallekGC:设置并行收集器
  • -XX:+UserConcMarkSweepGC:设置并发收集器
垃圾回收统计信息
  • -XX:+PrintGC
  • -XX:+PrintGCDetails
  • -Xloggc:filename:把信息记录到文件中,而不是打印到后台

Tomcat优化设置

  • set JAVA_OPTS= 确定一个服务器上有几个虚拟机,来确定给虚拟机多大内存,
  • -Xms4g:
  • -Xmx4g:
  • -Xss512k
  • -XX:+AggressiveOpts:凡是虚拟机里能用到的优化选项都用上
  • -XX:+UserBiasedLocking:启用偏向锁
  • -XX:PermSize=64M
  • -XX:MaxPermSize=300M
  • -XX:+DisableExplicitGC:不让显示调用GC,也就是在程序中使用System.gc()也没用
  • JDK1.8中永久代变成元空间
  • -XX:+UserConcMarkSweepGC:使用CMS缩短响应时间,并发手机,低停顿
  • -XX:+UserParNeWGC:并行收集新生代的垃圾
  • -XX:+CMSParrllelRemarkEnabled:在使用UserParNewGC的情况下,尽量减少mark的时间
  • -XX:+UserCMSCompactAtFullCollection:使用并发收集器时,开启对老年代的压缩,使碎片减少
  • -XX:LargePageSizeInBytes=128m:内存分页大小对性能的提升
  • -XX:+UserFastAccessorMethods:get/set方法转成本地代码
  • -Djava.awt.headless=true:修复linux下tomcat处理图表时可能产生的一个bug

性能设置

  • 一个服务器上跑了一个Tomcat,提供了一个服务,如何知道这个服务能并发访问,并且响应时间比较快
  • 起一万台机器,每台机器上开启一万个线程,这些不停的去访问这个服务器上的一个页面,看这个服务器能否撑得住
  • 使用自动化测试工具来进行性能设置,如LoadRunner,Selenium,JMeter(免费)
  • JMeter具体如何配置进行性能化设置,并观察结果

展开阅读全文

没有更多推荐了,返回首页