jvm的结构以及如何调优

        元空间:从jdk1.8开始的叫法,其实就是以前的方法区;但是和方法区也有区别;方法区的数据保存在JVM内存中,元空间的数据保存在物理磁盘上;

.Java文件转换成.class文件,通过类加载子系统 加载到内存中去(方法区),所有的代码都在元空间

  •      类加载子系统:将所有的.class文件数据加载到元空间,以方便运行调用;
  •      程序执行引擎:执行代码,并会将执行到的代码的行数记录到程序计数器中
  •       程序计数器:记录当前代码运行到了哪一行 
  •       本地方法栈:服务于本地(native)方法的本地方法内存的所有局部变量都保存到本地方法栈中,其内部结构和栈相同,都是为调用的方法分配栈帧区域,该方法内部的局部变量保存在这个栈帧中
  •       栈:叫虚拟机栈或者线程栈,即会为每个线程分配一个区域,在该线程内部调用方法时,会在该区域中为方法开辟一块栈帧区域,方法的内部的局部变量都保存在该栈帧区域中
  •       堆:存放对象

堆:

内部结构JDK1.8:

     采取分代思想,堆中分为年轻代和老年代

     年轻代:老年代=1:2;

老年代保存的对象:

                1.创建时太大的对象会直接保存到年老代中

                 2.从年轻代中产生,年代数达到15的对象

年轻代:

Eden区(伊甸园区):新创建的任何对象都在这里

经过GC清理过后仍幸存的对象存在幸存者区

当伊甸园区内存不足时会触发minnor gc,当伊甸园区出发GC之前会通过可达性分析算法得到当前使用的对象,会把使用的对象复制到s区,随机一个,俩个不是同时开启的,进去之后年代数增1,minnor gc会把伊甸园区和另一个s区清空;在运行在产生新对象,以此类推,就是这个迭代循环过程,当s区的年代数达到15时(一般不容易),会把它存放到老年代中,这个对象即将长久存在

 年轻代工作原理总结:

新创建的对象会保存在Eden区,当Eden区内存不足时,会触发minnor gc,会对整个年轻代进行回收,再回收之前,会使用可达性分析算法,从栈开始,标记所有正在使用的对象,将使用的对象保存到s0区,然后堆Eden和s1区进行回收,保存到s区的对象年代数会加1.后续若再次Eden内存不足时,将正在使用的对象会存入到另一个s(s1)区,然后对Eden和s0进行回收,当对象的年代数达到15,会移入年老代中

s(suvivor 幸存者)0区:

s(suvivor 幸存者)1区:

伊甸园区:s0:s1=8:1:1

老年代:

 老年代中保存到的对象和年代数达到15的对象,当老年代内存不足时,会触发full gc,会堆整个堆内存进行回收,且会造成STW(stop the world),用户会有卡顿体验,若频繁的触发full gc,用户的体验非常差,此时就需要进行JVM优化

注: minor gc和full gc都会出发STW,但是minor gc回收内存小,所以造成的卡顿几乎感觉不到,所以minor gc触发频发频率可以高,但是full gc是对整个堆内存的回收,造成的卡顿用户感觉很明显,所以尽可能的减少full gc 触发;

栈:

mian栈帧:
  int i=1;
  int b=4;
  change(i,b);
  ........
  change()
  int a=1;
  int b=2;
  int c=a+b;

 再点class文件中运行:

 为mian线程分配的栈空间:

 

栈帧内部的四块区域

  1. 局部变量表:保存我们一直一直知道的局部变量,包括他的数据
  2. 操作数栈:保存的是中间过程可能涉及到的任何操作数;任何操作数如果要取都得出栈,如果 产 生 都得进行入栈操作
  3.  动态链接:所有方法上的代码都是保存到元空间的,保存一行行的数据;保存当前方法在元空间的地址,如果别人想调用,来动态链接一看,就可以去元空间查找
  4. 方法出口: 保存当前方法执行结束要返回原来方法的某个行号,它会保存其他每个方法的行号(程序器技术器调用),保存的是字节码中的行号

 

 JVM调优措施:

 1.尽可能减少大对象的产生

                ------------操作文件时,尽可能多次操作

2.尽可能让对象在年轻代在年轻代被回收走

          -------------尽可能的扩大年轻代的大小

  •    直接扩大堆内存大小
  •    调整年轻代的比例                  

                       ------可以调整Eden和俩个s区的比例

                       --------调整年轻代和老年代的比例(慎用) 

3.更换GMSGC为G1GC

JVM堆内存的大小调整

 

 

 

 永久代:元空间,并不存在于堆

    GC的分类:

    SerialGC:单线程

    ParalleGC: 并发情况下作用的GC

   ConcMarkSweepGC:并发情况下作用的GC

                  ------JDK1.5开始默认提供的  

   G1GC:   从JDK1.9开始默认提供的          

 G1GC回收机制:

有一个后台线程记录当前回收利用率最高的块,将其作为最优先回收的块,当内存不足时,

对该块进行回收,若回收后够用,则不再继续回收,大大降低STW的时间

注意:每个块在下次使用时作为不同的去使用

 Gc垃圾回收机制常用算法:

  1. 复制算法----minor gc使用
  2. 标记---清除算法 特点:回收后的内存不连续,内存利用率低
  3. 标记---整理算法   ---回收后将使用的对象进行整理,然后将可利用的内存整理到一起,实现内存连续
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Liamlf

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值