
jvm
文章平均质量分 75
云原生之家
这个作者很懒,什么都没留下…
展开
-
深入理解Java虚拟机笔记---原子性、可见性、有序性
Java内存模型是围绕着并发过程中如何处理原子性、可见性、有序性这三个特征来建立的,下面是这三个特性的实现原理:1.原子性(Atomicity) 由Java内存模型来直接保证的原子性变量操作包括read、load、use、assign、store和write六个,大致可以认为基础数据类型的访问和读写是具备原子性的。如果应用场景需要一个更大范围的原子性保证,Java内存模型还提供了loc原创 2014-12-16 22:43:21 · 6031 阅读 · 3 评论 -
深入理解Java虚拟机笔记---方法表集合
方法表的结构与字段表一样,依次包含了访问标志(access_flags),名称索引(name_index),描述符索引(descriptor_index),属性表集合(attributes)几项,如下表所示:因为volatile关键字和transient关键字不能修改方法,所以方法表的访问标志中没有了ACC_VOLATILE与ACC_TRANSIENT标志。与之相对的,synchroniz原创 2014-12-13 11:35:34 · 2111 阅读 · 0 评论 -
深入理解Java虚拟机笔记---属性表集合
在Class文件,字段表,方法表中都可以携带自己的属性表集合,以用于描述某些场景专有的信息。与Class文件中其它的数据项目要求的顺序、长度和内容不同,属性表集合的限制稍微宽松一些,不再要求各个属性表具有严格的顺序,并且只要不与已有的属性名重复,任何人实现的编译器都可以向属性表中写入自己定义的属性信息,Java虚拟机运行时会忽略掉它不认识的属性。为了能正确地解析Class文件,《Java虚拟机规范原创 2014-12-13 15:10:49 · 4667 阅读 · 2 评论 -
深入理解Java虚拟机笔记---引用类型和对象是否死亡
在JDK1.2以前,Java中的引用定义得很传统:如果reference类型的数值代表的是另外一块内存的起始地址,就称这块内存代表中一个引用。这种定义很纯粹,但太过狭隘,一个对象在这种定义下只有被引用或者没有引用两种状态,对于如何描述一个“食之无味,弃之可惜”的对象就显得无能为力;如果内存在进行垃圾收集后还是非常紧张,则可以抛弃这些对象。很多系统的缓存功能都符合这样的应用场景。 在JDK1原创 2014-12-13 15:42:32 · 1285 阅读 · 0 评论 -
深入理解Java虚拟机笔记---字段表集合
字段表(field_info)用于描述接口或类中声明的变量。字段(field)包括了类级变量或实例变量,但不包括方法内部声明的变量。描述一个字段的信息有:字段的作用域(public,private,protected修饰符),是类级变量还是实例级变量(static修饰符),可变性(final),并发可见性(volatile修饰符,是否强制从主内存读写),是否可序列化(transient修饰符),字原创 2014-12-12 21:47:26 · 1997 阅读 · 0 评论 -
深入理解Java虚拟机笔记---类加载时机
类从被加载到虚拟机内存中开始,到缷载出内存为止,它的整个生命周期包括了:加载(Loading),验证(Verification),准备(Preparation),解析(Resolution),初始化(Initialization),使用(Using),缷载(Unloading)七个阶段。其中验证,准备,解析三个阶段统称为连接(Linking)阶段,这七个阶段的发生顺序如下图: 加载,验原创 2014-12-13 18:56:46 · 1202 阅读 · 0 评论 -
深入理解Java虚拟机笔记---运行时栈帧结构
栈帧(Stack Frame)是用于支持虚拟机进行方法调用和方法执行的数据结构,它是虚拟机运行时数据区的虚拟机栈(Virtual Machine Stack)的栈元素。栈帧存储了方法的局部变量表,操作数栈,动态连接和方法返回地址等信息。第一个方法从调用开始到执行完成,就对应着一个栈帧在虚拟机栈中从入栈到出栈的过程。 每一个栈帧都包括了局部变量表,操作数栈,动态连接,方法返回地址和一些额外的原创 2014-12-14 12:40:59 · 19306 阅读 · 0 评论 -
深入理解Java虚拟机笔记---类加载过程
一、加载 “加载”(Loading)阶段是“类加载”(Class Loading)过程的一个阶段。在加载阶段,虚拟机需要完成以下三件事情:a.通过一个类的全限制名来获取定义此类的二进制字节流。b.将这个字节流所代表的静态存储结构转化为方法区的运行进数据结构。c.在Java堆中生成一个代表这个类的java.lang.Class对象,作为方法区这些数据的访问入口。 虚拟机规原创 2014-12-14 00:05:49 · 1580 阅读 · 0 评论 -
深入理解Java虚拟机笔记---方法调用
方法调用并不等同于方法执行,方法调用阶段唯一的任务就是确定调用方法的版本(即调用哪一个方法),暂时还不涉及方法内部的具体运行过程。在程序运行时,进行方法调用是最普遍、最频繁的操作。在Class文件的编译过程中不包含传统编译中的连接步骤,一切方法调用在Class文件里存储的都只是符号引用,而不是方法在实际运行时内存布局中的入口地址(相当于直接引用)。这个特性给Java带来了更强大的动态扩展能力,但也原创 2014-12-14 14:48:03 · 3052 阅读 · 2 评论 -
深入理解Java虚拟机笔记---双亲委派模型
站在虚拟机的角度上,只存在两种不同的类加载器:一种是启动类加载器(Bootstrap ClassLoader),这个类加载器使用C++语言实现,是虚拟机自身的一部分;另外一种就是其它所有的类加载器,这些类加载器都由Java语言实现,独立于虚拟机外部,并且全部继承自java.lang.ClassLoader。 从Java开发人员的角度看,类加载器还可以划分得更细一些,如下:1.启动类加载原创 2014-12-14 12:38:11 · 14100 阅读 · 0 评论 -
深入理解Java虚拟机笔记---访问标志
常量池结束之后,紧接着的2个字节代表访问标志(access_flags),这个标志用于识别一些或接口层次的访问信息,包括:这个class是类还是接口;是否定义为public类型;是否定义为abstract类型;如果是类的话,是否被声明为final,等等。具体的标志五个一标志的含义如下表:access_flags中一共有32个标志位可以使用,当前只定义了其中的8个,没有使用到的标志位要求一律原创 2014-12-11 20:54:14 · 1751 阅读 · 2 评论 -
深入理解Java虚拟机笔记---类索引,父类索引,接口索引集合
类索引(this_class)和父类索引(super_class)都是u2类型的数据,而接口索引(interfaces)是一组u2类型的数据集合,class文件中由这三项数据来确定这个类的继承关系。类索引用于确定这个类的全限定名,父类索引用于确定这个类的父类的全限定名。由于Java语言不允许多继承,所以父类索引只有一个,除了java.lang.Object之外,所有的Java类都有父类,因了除了j原创 2014-12-11 21:05:29 · 1678 阅读 · 0 评论 -
深入理解Java虚拟机笔记---内存分配与回收策略
Java技术体系中的自动内存管理最终可以归结为自动化地解决了两个问题:给对象分配内存以及回收分配给对象的内存。对象的内存分配往大的方向上讲,就是在堆上分配,对象主要分配在新生代的Eden区上,如果启动了本地线程分配缓冲(-XX:+UseTLAB,默认已开启),将按线程优先在TLAB上分配。少数情况下也可能会直接分配在老年代中,分配的规则并不是百分之百固定的,其细节取决于当前使用的是哪一种垃圾收集器原创 2014-12-10 13:41:46 · 1353 阅读 · 0 评论 -
深入理解Java虚拟机笔记---内存模型
主内存与工作内存 Java内存模型的主要目标是定义程序中各个变量的访问规则,即在虚拟机中将变量存储到内存和从内存中取出变量值这样的底层细节。此处的变量(Variable)与Java编译中所说的变量略有区别,它包括了实例字段,静态字段和构成数组对象的元素,但是不包括局部变量与方法参数,因为后者是线程私有的,不会被共享,自然就不存在竞争的问题。了为获得比较好的执行效率,Java内存模型并没有限原创 2014-12-15 20:50:34 · 1241 阅读 · 0 评论 -
方法调用指令
在JDK7之前方法调用的字节码指令共有四条,invokeinterface、invokespecial、invokestatic、invokevirtual。由这四条指令完成Java中所有类型方法的调用。invokeinterface(调用接口方法) 无符号数indexbyte1和indexbyte2共同组件一个当前类常量池索引(index),该索引值为(indexby原创 2014-12-18 21:39:00 · 1357 阅读 · 0 评论 -
JDK7动态方法调用
在JDK7中,Java提供了对动态语言特性的支持,实现了JSR 292 《Supporting Dynamically Typed Languages on the Java Platform》规范,这是Java语言发展的一重大进步,而提供对动态语言特性支持也是Java发展的一大趋势与方向。那么动态性表现在哪里呢?其一在Java API层面,新增了java.lang.invoke包,主要包含了Ca原创 2014-12-20 17:45:42 · 4654 阅读 · 1 评论 -
深入理解Java虚拟机笔记---判断对象是否存活
堆中几乎存放着Java世界中所有的对象实例,垃圾收集器在对堆回收之前,第一件事情就是要确定这些对象哪些还“存活”着,哪些对象已经“死去”(即不可能再被任何途径使用的对象)1.引用计数算法 很多教科书判断对象是否存活的算法是这样的:给对象中添加一个引用计数器,每当有一个地方引用它时,计数器值加1;当引用失效时,计数器减1;任何时刻计数器都为0的对象就是不可能再被使用的。 引原创 2014-12-05 17:27:20 · 1412 阅读 · 0 评论 -
深入理解Java虚拟机笔记---内存区域
Java虚拟机在执行Java程序过程中会把它所管理的内存划分为若干个不同的数据区域。这些区域有自各的用途,以及创建及销毁时间,有的区域随着虚拟机进程的启动而存在,有些区域则是依赖用户线程的启动和结束而建立和销毁。根据《Java虚拟机规范(第2版)》规定,Java虚拟机管理的内存区域包括以下几个运行时数据区域,下如图1.程序计数器(Program Counter Register)原创 2014-12-05 16:35:51 · 1316 阅读 · 0 评论 -
深入理解Java虚拟机笔记---垃圾收集器
如果说收集算法是内存回收的方法论,那么垃圾收集器就是内存回收的具体实现。Java虚拟机规范中对象垃圾收集器应该如何实现并没有任何规定,因此不同的厂商,不同版本的虚拟机所提供的收集器可能会有很的差别,并且一般会提供参数供用户根据自己的应用特点和要求组合出各个年代所使用的收集器。下面是Sun HotSpot虚拟机1.6版本Update22包含的所有收集器:上图中,如果两个收集器之间存在连线,就原创 2014-12-09 17:18:07 · 1118 阅读 · 0 评论 -
深入理解Java虚拟机笔记---垃圾收集算法
当对象判定为"已死"状态,虚拟就要采取一定的手段将这些对象从内存中移除,即回收垃圾,回收过程有采用一定的算法。如下是一些主要的垃圾收集算法:1.标记-清除算法 该算法是最基础的算法,分为“标记”和“清除”两个阶段:首先标记出所有需要回收的对象,在标记完成后统一回收掉所有被标记的对象。之所有说它是最基础的算法是因为后续的收集算法都是基于这种思路并对其缺点进行改进得到的。它的缺点主要有两个原创 2014-12-09 09:44:57 · 1189 阅读 · 0 评论 -
深入理解Java虚拟机笔记---class类文件魔数,版本,常量池
魔数 每个class文件的头4个字节称为魔数(Magic Number),其值为:0xCAFEBABE,它的唯一作用是用于确定这个文件是否为一个能被虚拟机接受的class文件。使用魔数而不是扩展名来进行识别主要是基于安全的考虑,因为文件的扩展名可以随意地被改动。版本号 紧接着魔的4个字节存储的是class文件的版本号:第5和第6个字节是次版本号(Minor Version),第...原创 2014-12-11 16:10:39 · 4391 阅读 · 3 评论 -
深入理解Java虚拟机笔记---class类文件结构概述
class文件是一组以8位字节为基础单位的二进制流,各个数据项目严格紧凑地排列在class文件中,中间没有任何分隔符。当遇到需要占用8位字节以上的的数据项时,则会按照高位在前的方式侵害成若干个8位字节进行存储。 根据Java虚拟机规范的规定,class文件格式采用一种类似于C语言结构体的伪结构来存储,这种伪结构只有两种数据类型:无符号数和表。无符号数属于基于数据类型,以u1、u2、u4、u原创 2014-12-11 13:53:37 · 1080 阅读 · 0 评论 -
深入理解Java虚拟机笔记---volatile变量的特殊规则
当一个变量定义成volatile之后,它将具备两种特性:第一是保证此变量对所有线程的可见性,这里的“可见性”是指当一条线程修改了这个变量的值,新值对于其它线程是可以立即得知的,变量值在线程间传递均需要通过主内存来完成,如:线程A修改一个普通变量的值,然后向主内存进行回写,另外一条线程B在线程A回写完成了之后再从主内存进行读取操作,新变量的值才会对线程B可见。 关于volatile变量的可见原创 2014-12-15 20:58:35 · 1961 阅读 · 0 评论