首先谈谈jvm调优的具体目的是
举个例子来说
对于电商商场系统给来说
假设现在是秒杀,那我们假设一秒有300人下单
假设每个订单的对象为1kb
下单还涉及到其他的对宪法,比如库存,优惠卷,积分等等
这里放大20倍
还可能设计到其他的操作
这里在放大10倍
所以总共是300kb2010=60M
这些对象在一秒后变为垃圾对象
在gc的过程中,jvm会stop The world,所以要进行一个优化,避免卡顿,不然用户体验极其不好
- GC的时间要足够的小
- GC的次数要足够的少
- 发生full GC的周期要足够的长
这个的本质是减少STW,stop the world,jvm在处理垃圾对象时,也就是gc时,它会把所有的用户线程暂停
这里思考一下,为什么gc要这么做?
对于在运行时数据区来说,线程是私有的,程序计数器,虚拟机栈,本地方法栈,这个3个区域是随着线程生灭,栈里的栈帧随着方法的进入和退出有条不紊的执行着出栈和入栈的操作,对于gc来说,首先它肯定是找gc root去不断的遍历,这个gc root是存放在线程栈中的局部变量表中,或者可能在方法区中的静态变量中,如果不进行STW的话,你在gc的过程中,线程死了,导致你的gc root也没了,也就是引用地址也没了,这说明这个对象也变成了垃圾对象,那整个的gc过程就会有点乱套,所以在gc的过程中,STW,暂停所有的线程,专心gc
jvm主要分为三个子系统
- 1.类加载器子系统
负责加载类文件,可以分为三个类加载器,分别是启动类加载器,类扩展加载器,以及应用程序类加载器 - 2.运行时数据区域
主要用于储存不同类型的数据
-
2.1.堆
主要存放new的对象
对于堆中来说,有三个区域,一个是eden区,一个是幸存区,eden区和幸存区是属于新生代区,一个是老年区,幸存区有s0,s1俩个区域,eden区如果被放满,会触发minor gc,这个是回收新生代的,如果old区被放慢,那么会触发full gc,新生代活过一次minor gc,年龄就会+1,到15就会放在老年区,full gc是回收所有的堆的,就不管你是新生区了还是老年区了 -
2.2.方法区
主要放常量,静态变量以及类信息 -
2.3.虚拟机栈(线程栈)
- 局部变量表
顾名思义,这个就是储存方法内的局部变量的地方 - 操作数栈
这个是操作局部变量的一些加减乘除的操作 - 动态链接
运行时确定如何连接(或者说关联)方法的调用到方法的实际代码的过程,通俗的说就是比如方法A调用了方法B,方法B有调用了方法C,这时你实际上调用的是方法C,所以它会动态的执行你实际上要执行的方法 - 方法出口
这个就是最后出口,顾名思义
一个方法就是一个栈帧,每个方法调用都会创建一个新的栈帧,并将其压入虚拟机栈的顶部,每个栈帧都有这四点
- 局部变量表
-
2.4.本地方法栈
就是一个native方法,实现底层是c++
-
2.5.程序计数器
记录代表即将执行代码的行数,这样是通俗的说,它实际上是存储了当 前线程正在执行的字节码指令地址。 -
3.执行引擎
解释字节码或将字节码编译成本地机器代码在执行,也可以修改程序计数器,以及垃圾收集线程