ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

【JVM】JVM基础知识串联

2021-07-09 20:32:25  阅读:217  来源: 互联网

标签:串联 对象 局部变量 基础知识 线程 垃圾 JVM GC 内存


在这里插入图片描述

一个方法对应一块栈帧内存区域。且这个区域是在虚拟机栈(线程栈)上分配的
在这里插入图片描述
这个线程栈就是用的数据结构中的栈(FILO:先进后出)。
为什么用栈的数据结构存放栈帧?因为先进后出的顺序和我们嵌套调用程序的执行顺序是一致的!
在这里插入图片描述
在这里插入图片描述

通过javap命令,对.class代码反汇编,将其存入一个txt文档,便于阅读
在这里插入图片描述
在这里插入图片描述

打开文件可以看到:
在这里插入图片描述
然后查JVM指令手册可以知道具体含义:

在这里插入图片描述

在这里插入图片描述
先在局部变量表中存入变量名,然后操作数栈中的2出栈,并赋值给局部变量表中的b。
然后到了上面的第4行:iload_1 ,查手册意思是:从局部变量1中装载int类型值:(操作数栈中又有了值)
在这里插入图片描述
然后是iadd:意思是执行int类型的加法,它会从操作数栈中弹出两个元素,做加法,并把计算的结果重新 压入 操作数栈
在这里插入图片描述
然后是bi push 10 :在操作数栈中 入栈 10
然后是imul:执行Int类型的乘法:操作数栈先后出栈10, 3,执行乘法运算=30,重新入操作数栈
然后来到第10行 istore_3,当前线程的 程序计数器的值 为 10(行号)
在这里插入图片描述
问:是谁改变的程序计数器的值?是它自己变化的吗?怎么被修改的?
答:程序计数器 只是一块内存空间,它不会自己改变值!
加载的Math.class文件需要字节码执行引擎去 执行, 所以它会知道当前执行到了哪里。所以是字节码执行引擎 改变的程序计数器的值。
在这里插入图片描述

为什么JVM中要设计程序计数器?
答:用于线程切换!当更高优先级的时间片执行完毕后,再回到原线程时,需要通过程序计数器记录的位置,继续执行
在这里插入图片描述
然后是10:istore_3,在局部变量表中先分配一块局部变量3(c对应的内存空间),然后11:iload_3:把30出栈赋值给c
然后12:ireturn 返回c

以上为内存分配的流转模型,分析方法都是一样的,javap命令和命令手册。
要学并发就得这么研究。

所以操作数栈就是 在程序运行过程中,开辟的一块 临时的 中转的 内存空间。

什么是动态链接
把符号引用转换为直接引用的,底层涉及大量C++实现
例如:
在这里插入图片描述
当在主线程中执行到compute()方法时,这个括号 属于一种符号引用,
compute()方法加载到方法区的内存地址放到动态链接中
通过动态链接可以找到compute()方法对应的一些代码。

方法出口
方法返回的出口一些信息,存在这个区域
在这里插入图片描述
每个栈帧都有这些区域(局部变量表,操作数栈、动态链接)

在这里插入图片描述
回看前面的程序,在main()中的math(局部变量内存空间)指向(存放了)一个堆的内存地址(math的内存地址)

以下就是栈和堆的联系
在这里插入图片描述
线程栈中,局部变量是引用堆的地址

方法区
在JDK1.8以前,叫永久代(持久代),在之后就叫元空间,开始使用操作系统的物理内存,不是堆内部的内存。
其中存放常量+静态变量+类信息
这些就是class加载到方法区之后的形成的一些信息

看最上面的代码:public static User user = new User();
静态变量user存放在方法区,其会引用堆区的user
所以方法区也可以画很多的箭头 引用堆区对象
在这里插入图片描述
最后讲一下本地方法栈:(现在用得不多了)
首先需要知道什么是本地方法
例如在调用一个线程时:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
这个start0就是本地方法,他用native修饰,本地方法栈就是存放本地方法的区域。
在这里插入图片描述
因此,蓝紫色的是每个线程都具备的,因此是线程私有的。而堆和方法区,是所有线程共享的。

下面说堆区:
堆内部 无非就是由年轻代,老年代组成。
年轻代有Eden区和Survivor区组成
在这里插入图片描述
当Eden区中的内存快满了,就会由字节码执行引擎,去执行minor GC做垃圾回收
在这里插入图片描述
垃圾如何收集?——可达性分析算法
在这里插入图片描述
上面说到,局部变量,静态变量,都是GC Roots,可达性分析算法会吧全部的GC Roots找出来,然后由此出发,找到引用的对象,一直往下,直到找到所有对象,最后一个成员变量不再引用任何其他对象为止。
凡是在这个引用链上的所有对象,GC过程中都会将其标记为“非垃圾”
在这里插入图片描述
标记为非垃圾的,会将其复制到 空着的 Survivor区
在这里插入图片描述
那么当GC结束了,剩下的还在伊甸园区的无引用对象会被回收。
经历过一次GC后存活下来的对象(复制到Survivor区域的对象)其年龄会+1

当下一次,伊甸园区又满了, 那么触发GC,minor GC会对整个年轻代进行回收,过程相同。在剩下的区域中未引用对象会被清理。
在这里插入图片描述
每经历一次GC。存活下来的对象的年龄都会+1,并在Survivor中两个小区对调位置(复制)
当年龄达到了15,那么这个对象会直接进入老年代
在这里插入图片描述
下面通过一个程序不断创建对象,来可视化GC过程:
在这里插入图片描述
在heapTests.add(new HeapTest())中创建的对象,始终不能回收,
因为heapTests引用了HeapTest(), 而heapTests又被外部的局部变量(GC Roots)引用。这些对象被判定为都不是垃圾对象
在这里插入图片描述
在这里插入图片描述
从上图可看到,当Eden区满了,会触发GC,并且Survivor0和Survivor1来回复制,随着GC次数增加,老年代区域内存增加。
那么当老年代内存满了怎么办?
字节码执行引擎会再开一条Full GC线程对整个堆区域做垃圾回收(包括年轻代和老年代)
在这里插入图片描述
当最后Full GC以后,还是没有内存空间,那么就会报OOM了。
在这里插入图片描述

JVM调优真正的目的?
主要减少FULL GC的次数,以及执行的时间。
减少STW:Stop the World,尽量减少STW的时间和次数
在垃圾收集线程执行时,会停掉用户线程。GC会影响性能。

蚂蚁金服问:为什么JVM要设计一个STW的机制?GC能否不设计STW,这样网站就不会卡顿了呀?
答:假设不STW,那么可能在GC过程中,如果线程提前结束了(方法结束),那么这部分内存都会出栈,整个线程栈对应的内存都会销毁掉。那么这个math这些局部变量引用的对象还在堆区,不会随线程结束而结束(堆区对象要GC过程才能回收),堆区对象可能会由非垃圾变为垃圾。也就是说如果没有STW,线程边执行,边执行GC回收,当堆区的对象的状态发生变化(非垃圾-变为垃圾),那么回收的程序不好设计,每次都要再去检查GC ROOTS。
所以不如STW快速做完垃圾回收工作。

垃圾收集器
每一种垃圾收集器都有STW机制,(过程、时机可能不一样)
在这里插入图片描述
在这里插入图片描述
分配JVM的参数:
在这里插入图片描述

线程运行时,每秒产生60MB的对象,会存放到Eden区
在这里插入图片描述
对象动态年龄判断机制
在这里插入图片描述

如果eden区中一批对象的总大小大于这块 Survivor区域 (S0)内存大小的50%,那么这个大对象会直接进入老年代。所以,每隔4-5分钟这个老年代区域就会被放满,触发FULL GC(问题所在

阿里面试题:能否对JVM调优,让其几乎不发生FULL GC?(允许可能一两次)
调优:
在这里插入图片描述

把年轻代Xmn调大一点,为2G,(老年代没必要太大为2G,调为1G),Eden区调为1.6G,那么S0,S1都为200M。
在这里插入图片描述

此时,产生的对象先到Eden区,约25s占满Eden区,之后触发Minor GC,存活下来的对象到S0/S1区时内存没有达到Survivor区域的50%.经过25S线程肯定早就结束了,那么在S0、S1中的对象相应也能够回收。就能够做到,垃圾对象能够一定在年轻代被回收,不会拖到老年代占用空间,所以性能有提升。
调优:
尽可能地让那些朝生夕死的垃圾对象,通过合理的JAVA虚拟机的各个内存区域之间的关系、比例,让垃圾对象在年轻代被干掉。

G1垃圾收集分类
在这里插入图片描述
G1垃圾收集器参数设::
在这里插入图片描述
在这里插入图片描述

标签:串联,对象,局部变量,基础知识,线程,垃圾,JVM,GC,内存
来源: https://blog.csdn.net/weixin_45595683/article/details/118604261

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有