![](https://img-blog.csdnimg.cn/20201014180756780.png?x-oss-process=image/resize,m_fixed,h_64,w_64)
JVM
文章平均质量分 79
深入理解JVM学习笔记
流光亦流连
这个作者很懒,什么都没留下…
展开
-
JAVA内存模型
一、JAVA内存模型简介JAVA内存模型的主要目的是定义程序中各种变量的访问规则,即关注在虚拟机中把变量值存储到内存和从内存中取出变量值这样的底层细节。这里的变量,包含实例字段,静态字段和构成数组对象的元素。这些变量都存在主内存中,多线程模式下,主内存是被多个线程所共享的,因此主内存中的变量存在线程安全问题,为此,JAVA内存模型中为每个线程添加了自己的工作内存。每个线程在工作时,从主内存中拷贝操作需要用到的变量的副本,存储在自己的工作内存中。二、内存之间的交互操作主要有以下8个基本操作原创 2021-09-28 20:47:54 · 62 阅读 · 0 评论 -
JAVA泛型
泛型的本质是参数化类型或者参数化多态和应用,即可以操作的数据类型指定为方法签名中的一种特殊参数。JAVA选择的泛型实现方式叫做“类型擦除式泛型”。具体来说就是泛型只在源码中存在,在编译后的字节码文件里,全部泛型都被替换为了原来的裸类型,并且在相应的地方插入了强制转型的代码。可以结合下面这段代码来理解。public void test1(){ ArrayList<String> ilist = new ArrayList<>(); Arra原创 2021-09-28 19:33:36 · 203 阅读 · 0 评论 -
静态分派与动态分派
JAVA语言的三大特性为:继承,封装,多态。分派调用过程将会揭示多态特性的一些最基本的体现,如重写和重载。一、静态分派在介绍静态分派前,先来看一段一段代码public class StaticDispatch { static abstract class Human{ } static class Man extends Human{ } static class Woman extends Human{ } public voi原创 2021-09-27 23:55:02 · 584 阅读 · 0 评论 -
JAVA虚拟机栈帧结构
在JAVA虚拟机中以方法作为最基本的执行单元,“栈帧”则是用于支持虚拟机方法调用和执行的数据结构。它也是虚拟机运行时数据区中的栈中的栈元素。从JAVA程序的角度来看,同一时刻,同一条线程里面,在调用堆栈的所有方法都同时处于执行状态。但对于执行引擎来讲,在活动线程中,只有栈顶的方法才是在运行的,即只有栈顶的方法是生效的,其被称为“当前栈帧”,与这个栈帧所关联的方法被称为"当前方法",执行引擎运行的所有字节码指令都只针对当前栈帧进行操作。栈帧中存储着方法的局部变量表,操作数栈,动态连接和方法返回地址。下原创 2021-09-27 21:27:05 · 189 阅读 · 0 评论 -
类与类加载器
一、类加载器实现"通过一个类的全限定名来获取描述该类的二进制字节流”这个动作放到JAVA虚拟机外部去实现以便让程序自己决定如何获取所需的类"功能的应用程序被称为类加载器。二、双亲委派机制JAVA虚拟机的类加载器可分为以下几类:1.启动类加载器:这个类加载器使用C++语言实现的,负责加载存放在$JAVA_HOME/lib目录下的类,或者被-Xbootclasspath参数所指定的路径中存放且能够被JAVA虚拟机识别的类库加载到虚拟机的内存中。启动类加载器无法被JAVA程序直接引用,自定义加载器原创 2021-09-26 19:57:50 · 163 阅读 · 0 评论 -
虚拟机类加载机制
类的生命周期可以分为加载,验证,准备,解析,初始化,使用和卸载7个阶段。其中验证,准备,解析三个部分统称为连接。其中类的加载,验证,准备,初始化,卸载这五部的顺序是确定的,但解析阶段则不一定,它在某些情况下可以等到初始化阶段后在开始,主要是为了支持JAVA语言的动态绑定特性。1.类的加载加载过程中JAVA虚拟机需要完成三件事:1)通过一个类的全限定名来获取定义此类的二进制字节流。2)将这个字节流所代表的静态存储结构转化为方法区的运行时数据结构。3)在内存中生成一个代表这个类的j.原创 2021-09-26 15:50:47 · 58 阅读 · 0 评论 -
经典垃圾收集器
一、Serial收集器通过名字就可以知道这是一个单线程收集器,这里的单线程并不仅仅指它会用一个线程去完成垃圾收集工作,更重要的是强调它在垃圾回收时,必须要暂停其他所有的工作,直到垃圾回收结束。其运行示意图如下:尽管Serial收集器在垃圾收集的过程中会伴随着长时间的STOP THE WORLD,但它仍是HotSpot虚拟机运行在客户端模式下的默认新生代收集器,它相比于其他垃圾收集器,最大的优势在于简单高效,而且它的额外内存消耗是所有垃圾收集器里面最小的。由于客户端分配给虚拟机的内存并不会原创 2021-09-25 21:21:14 · 53 阅读 · 0 评论 -
HotSpot垃圾回收算法的细节分析
一、根节点枚举根据之前的博文,我们已经了解了可达性分析算法,那么这个算法具体是怎么在HotSpot中实现的呢?首先,JVM需要标记直接与GC roots相连的对象,但这个过程必须要暂停其他用户进程,即stop the world(以下简称STW)。因为与GC roots直接相连的对象是可达性分析算法准确性的关键,关系着对象能否被正确地进行标记。但用户线程停顿下来之后,并不需要检查完所有上下文和全局引用的位置来找到被GC roots直接引用的对象,这太费时间了。为了提高效率,JVM中会维护一个Oo原创 2021-09-15 09:51:41 · 184 阅读 · 0 评论 -
JVM经典垃圾回收算法
一、标记-清除算法该算法分为标记和清除两个阶段。标记阶段基于可达性分析,具体原理可以参照我之前的博客文章。可达性分析阶段会标记出所有存活的对象(也可以标记死亡的对象,原理类似)。在标记完成后,将回收所有的死亡对象。具体图解如下:从图中我们可以看出这个收集方法的缺点:就是会产生大量的不连续的内存碎片,有可能提前引发一次FullGC(),进而影响其他程序的工作。除此之外,如果JAVA堆中包含了大量的对象,那么标记的过程将十分费时,同时,清理的过程会随着对象的增多而耗费更多的时间。二、复制算法原创 2021-09-14 22:03:18 · 59 阅读 · 0 评论 -
JVM垃圾回收算法——对象的存活与销毁
一、如何判断对象是否存活判断对象是否存活主要有两种方法。一是引用计数法。其主要原理为每当一个对象在一个地方被引用,其计数值就+1,引用失效时,计数值-1。但现在JAVA虚拟机里并没有选择引用计数法来管理内存,因为它有两个弊端:1.在对象较多时,维护引用计数需要占用大量内存。2.引用计数法无法解决循环引用的问题。有关循环引用问题,可以参考下面这段代码public class ReferenceGC { public Object instance = null;原创 2021-09-14 09:36:17 · 245 阅读 · 0 评论 -
JVM对象的创建与访问定位
一、JVM中对象的创建JVM中创建对象的过程可以分为以下几步:1.当JVM遇到一条new指令时,首先去检查这个指令的参数能否在常量池中定位到一个类的符号引用,并检查这个符号代表的类是否被加载,解析和初始化过。若没有,应先加载该类。2.若类已被加载,需要在内存中为其分配相应的空间。这里提一下内存空间的维护,有两种方式,一种时采用指针碰撞的方式,即维护一个指针用于记录空闲的内存空间的地址,当为对象分配地址空间之后,指针进行相应的移动。或者采用空闲列表记录系统中可用的内存地址空间。3.原创 2021-09-11 14:15:25 · 329 阅读 · 0 评论 -
JVM内存模型
JVM的内存模型如图所示。根据JVM内存模型,可将运行时的数据区分为以下几类一、程序计数器程序计数器时一块较小的空间,可以把它看作记录所执行的字节码文件的行号治时期,我们需要通过它来定位到接下来索要执行的字节码指令的地址。在多线程操作的过程中,为了保证线程上下文切换后仍能找到之前切换时的执行位置,每个线程都需要有一个独立的程序计数器,这个程序器记录的就是线程在上下文切换时的执行位置。各个线程之间的程序计数器互不影响,独立存在。 如果线程正在...原创 2021-09-10 10:35:55 · 59 阅读 · 0 评论