jvm调优

Posted 750657961

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了jvm调优相关的知识,希望对你有一定的参考价值。

 

 

jvm运行时内存空间:

 

方法区     jvm虚拟机栈      本地方法栈
{    java堆        }       程序计数器
  |          |
  |          |
执行引擎---->本地接口 --->本地方法库



程序计数器:
  进程切换时用户保留现场
jvm虚拟机栈:
  保存参数,局部变量,中间计算过程和其他数据。
  每个方法被执行时多会创建一个栈帧(每个方法执行,对应一个栈帧在虚拟机栈中冲入栈道出栈的过程)
本地方法栈:
  和java虚拟机栈作用类似(不同点是:虚拟机执行java方法时使用的)
jvm堆:
  存放对象和实例
  当前主流的虚拟机堆内存都是按照可扩展来实现的(通过-Xmx和-Xms控制)。
  如果在堆中没有内存完成实例分配,并且堆也无法再扩展时,将会抛出OutOfMemoryError异常。
  年轻代+年老代+持久代的部分
方法区:"持久代的部分"(Permanent Generation)
  用于存储已被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等

 

堆内存结构:
Young                     Old              Permanent
Eden 、        Survivor
Eden 、     From 、     To

 

 

非堆内存:

  (Permanent持久代(部分在堆内存中))

 

 


-Xss 栈内存:

  (默认1M)(每线程使用)

-Xms:

   star heap (默认物理内存的1/64 <1GB )
-Xmx:

  max heap (默认物理内存1/4 <4GB)

建议-Xms = -Xmx 避免gc后,调整堆大小,减少系统内存分配开销

 


-Xmn:

  young区大小 (默认堆的3/8 )
-XX:NewRatio:
  年轻代/年老代 的比值
  设置了Xms=Xmx的情况下该参数不用设置
-XX:SurvivorRatio:
  E / S 的比值 (默认是8)

 


old区:

  (-Xmx 减去 -Xmn 减去 持久代)
  年轻代中经过垃圾回收没有回收掉的对象被复制到年老代
  年老代存储对象比年轻代大,而且不乏大对象,eg:缓存、、


-XX:PretenureSizeThreshold=1024(默认0,多进入E区)
  创建的对象超过1024时直接进入年老代

 


弱引用对象:
  新生代未回收的对象大于年老代的值就会回出现FGC
  FGC:

    回收整个堆内存,然后把新生代未回收的值放入堆内存
强引用对象:
  出现FGC,直接OutOfMemor


持久代:(方法区)
  存放class、Method元信息、类、方法
  -XX:PermSize     初始大小
  -XX:MaxPermSize   最大值
  建议 -XX:PermSize等于-XX:MaxPermSize
  一般设置为128M (以最快的方式做好事情:监控该值,发现不足,调大(要停机))

 

调优:
  所有的调优多需要有个指标,不然多是扯淡。

 

 

jvm垃圾回收机制:


垃圾收集算法:
  1、引用计数(被抛弃了)
  2、根搜索算法


jvm垃圾回收算法:
  1、复制算法
    E-->S (新生代大部分是不存活的了)
    从根集合扫描,将存活的对象复制到一块新的没有使用的空间,清楚不存活的
  2、标记清除算法
    适合老生代回收
    从根集合扫描,对存活对象进行标记后,再扫描整个空间未被标记的对象进行回收,并更新指针进行对象移动(产生成本),解决内存碎片问题。
  3、标记整理压缩算法



垃圾回收器:
  新生代:(复制算法)
    Serial 、 ParNew 、Parallel Scavenge
  年老代:(标记清除算法、标记整理压缩算法)
    CMS 、 Serial old 、Parallel old



串行回收:
  gc单线程内存回收,会暂停所有的用户线程 (没有多线程交互单线程回收更高效) serial串行回收器
  -XX:+UseSerialGC 开启 (新生代和年老代开启方法一样)
    开启后使用:Serial New + Serial Old 组合回收

并行回收:
  多个gc进程并行工作,但此时用户线程是暂停的, Parallel收集器
  -XX:+UseParNewGC 开启ParNew
    开启后:新生代使用并行回收器,年老代使用串行回收器
    -XX:ParallelGCThreads 指定线程数(最好与cpu核心相当)
  -XX:+UseParallelGC 开启Parallel Scavenge
    开启后:使用Parllel Scavenge + Serial Old 组合回收
    -XX:GCTimeRatio 设置用户执行时间占总时间百分比,默认99
    -XX:MaxGCPauseMillis 设置GC最大停顿时间
  -XX:+UseParallelOldGC 开启Parallel Old回收
    开启后使用:Parallel Scavenge + Parallel Old 组合回收

并发回收:
  用户线程和gc线程同时执行(不一定是并行),不需要停止用户线程(暂停非常短) CMS收集器(并发标记清除)
  -XX:+UseConcMarkSweepGC 开启CMS
    开启后使用:ParNew + CMS + Serial Old
    (Serial Old 作为CMS出现问题后的备用收集器)
    两种回收失败:
      CMS还没有到达回收的阈值,新生代存活对象过来了,但是年老代空间不足(触发FGC)。
      CMS回收过程中(未回收完),新生代存活对象过来了(触发FGC),
    -XX:ParallelCMSThreads 设置线程数(默认:(ParallelGCThreads+3)/4)
      IO密集型:cpu核数*2+1
      cpu密集型:cpu核数+1
    -XX:CMSlnitiatingOccupancyFraction
      设置在年老代被使用多少后发起垃圾回收(默认68%)
    -XX:+UseCMSCompactAtFullCollection
      由于CMS收集器会产生碎片,设置后再CMS垃圾回收后进行一次内存碎片整理过程
    -XX:+CMSFullGCBeforeCompaction
      设置CMS在收集若干次后再进行一次内存整理
    -XX:CMSlnitiatingPermOccupancyFraction
      设置Perm Gen使用达到多少是触发(默认92%)

性能指标:
吞吐量:
  应用花在非GC上的时间百分比
GC负荷:
  应用花在GC上的时间百分比
暂停时间:
  GC暂停时间
GC频率:
  GC发生的频率
反应速度:
  对象回收时间


年轻代大小选择:
  响应时间优先应用
    尽可能设大,直到接近系统最低响应时间
  吞吐量优先的应用:
    尽可能大
  避免设置过小:
    YGC频繁

年老代大小选择:
  响应时间优先:

    CMS

 

以上是关于jvm调优的主要内容,如果未能解决你的问题,请参考以下文章

JVM调优经验分享

JVM性能调优1:JVM性能调优理论及实践(收集整理)

JVM性能调优

JVM性能调优

jvm性能调优都做了啥

JVM参数调优详解