JVM总结

第二章

一、Java运行时的数据区域:

 
   

(1)程序计数器:程序计数器用于存储正在执行的虚拟机字节码指令的地址,每个线程有自己独立的程序计数器

(2)虚拟机栈:

1)虚拟机栈是线程私有的,虚拟机栈是java方法执行的内存模型,每个方法在执行的同时都会创建一个栈帧用于存储局部变量、操作数帧、动态链接、方法出口等信息。每个方法从调用到执行完成的过程就对应着一个栈帧在虚拟机栈中入栈到出栈的过程。

2)局部变量表存放了编译器可知的各种基本数据类型、对象引用和指向一条字节码指令的地址。

3)当线程请求的栈深度大于虚拟机所允许的深度,将抛出StackOverflowError异常;如果虚拟机栈可以动态扩展,如果扩展时无法申请到足够的内存时,就会抛出OutOfMemoryError异常

(3)本地方法栈

本地方法栈与虚拟机栈作用十分相似,只不过本地方法栈为虚拟机执行java代码服务而本地方法栈则是为本地方法提供服务。

(4)堆

1)Java堆是虚拟机管理的最大的一块内存。Java堆被线程所共享。因为java堆是GC主要管理的部分因此也被称为GC堆。

2)Java堆可分为新生代和老年代。

3)线程还可以在堆上为自己划分出多个线程私有的分配缓冲区。

4)如果堆上有实例未能分配到内存上并且堆也无法再扩展了,将会抛出OutOfMemoryError异常

(5)方法区

方法区与java堆一样,是各个线程共享的内存区域,它用于存储已被虚拟机加载的类信息、常量、静态变量、及时编译器编译后的代码等数据。

该部分的垃圾回收主要目标是对常量池的回收和对类型的卸载(1.8后将字符串常量池放到堆中了)

(6)运行时常量池

运行时常量池属于方法区的一部分。常量池用于存放编译器生成的各种字面量和符号的引用,这部分内容将在类加载后进入方法区的运行时常量池。

Java语言的动态性可以使得运行期也可以将新的常量放入常量池中。(String 的intern()方法,所有字面值字符串和字符串赋值常量表达式都使用 intern 方法进行操作。)

(7)直接内存

NIO类:引入了一种基于通道与缓冲区的I/O方式,它可以使用Native函数库直接分配堆外内存,然后通过一个存储在Java堆中的DirectByteByffer对象作为这块内存的引用进行操作。

二、HotSpot虚拟机中的对象

(1)对象的创建

1)虚拟机在创建对象时是先检查该类是否加载完整,然后为该对象分配内存(内存分配有a.指针碰撞方式:基于内存是规整的;b.空闲列表:内存是零碎的),分配完内存初始化每个变量为默认值,再执行对象的初始化。

(2)对象的内存布局:

对象在内存中布局可分为3块区域:对象头、实例数据、对齐填充

对象头:存放对象的自身运行时数据如哈希码、GC分代信息、锁等。还有类型指针用于指向这个对象是哪个类的实例

(3)对象的访问定位

对象的访问分为两类:句柄和直接指针

句柄:java堆中划分出一段内存用作句柄池,引用存储的是对象句柄的地址,句柄中包含了具体对象的地址。

第三章 垃圾回收及内存管理

一、对象已死:

1)可通过引用计数器来判断对象是否有用,但该方法可能导致内存泄漏

2)可达性分析:由起始点开始向下搜索来判断哪些对象是活的哪些对象是死的。

3)引用可分为:

a)强引用

b)软引用:当内存不足时,GC对软引用进行对象回收,若回收后内存任然不足,这抛出内存溢出异常

c)弱引用: 只能存活到下一次GC时。

d)虚引用:设置虚引用的目的是在一个对象被收集器回收时收到一个系统通知。

4)finalize方法

若该对象的finalize方法没被覆盖或者被虚拟机执行过一次,那么将不执行finalize方法,finalize方法不一定执行。

二、回收方法区

方法区也是会被回收的,当没有引用指向常量时,该常量就会被清理。

当一个类被认为是无用类时才会被卸载。

三、GC回收算法

1)标记清除算法:标记出要清除的对象,然后清除。缺点是会产生大量的空间碎片

2)复制算法:两块内存,当清除时将存活的对象复制到另一块内存中。不过根据研究表明可以8:1的比例用于划分两块内存。

3)标记整理算法:如同紧凑技术

(2)垃圾收集器(未看)

(3)Full GC和Minor GC

1)Full GC/Major GC:指发生在老年代的GC,出现了Full GC一般至少伴随一次Minor GC,Full GC一般的速度一般比Minor GC慢十倍以上

2)Minor GC:指发生在新生代的垃圾收集动作。

四、内存分配策略:

1)对象优先分配到新生代Eden区中

2)大对象直接进入老年代

3)长期存活的对象将进入老年代

4)动态对象年龄判定:

如果在Survivor空间中相同年龄的所以对象大小的和大于Survivor空间的一半,年龄大于或等于该年龄的对象就可以直接进入老年代

5)空间分配担保:

在发生Minor GC前,虚拟机检查老年代最大可用空间是否大于新生代所有对象总空间,如果是,那么这次Minor GC就是安全的。如果不是,则虚拟机会查看HandlePromotionFailure设置值是否允许担保失败。若允许则检查老年代最大可用连续空间是否大于历次晋升到老年代的对象的平均大小,若大于则尝试Minor GC否则Full GC。

新生代使用复制收集算法所以用Survivor空间作为乱换备份,因为当出现大量对象在Minor GC后任然存活,则需要老年代来进行担保

第七章 虚拟机类加载机制

一、类加载的时机

(1)类加载的生命周期包括:加载、验证、准备、解析、初始化、使用、和卸载。其中验证、准备、解析三个部分统称为连接。

必须对类初始化的五种情况:

1)遇到new、getstatic、putstatic、或invokestatic这四条字节码指令时,进行初始化。

2)使用java.lang.reflect包的方法对类进行反射时

3)当初始化一个类,而其父类未初始化

4)当虚拟机启动时,用户需要指定一个要执行的主类,虚拟机会先初始化这个主类

5)1.7的动态语言支持??

(2)被动引用的例子

1)子类引用父类的静态变量不会初始化子类

2)定义数组不会导致初始化

3)单纯的引用静态常量时(编译器优化导致)

接口和类的初始化区别在于:一个类初始化要求他的父类必须都已初始化过,但一个接口则不要求,只有在真正使用到父接口的时候才会初始化

二、类加载器

(1)通过一个类的全限定名来获取描述此类的二进制字节流,这个动作放在java虚拟机外部去实现,以便让应用程序自己决定如何去获取所需要的类。实现这个动作的代码模块称为“类加载器”

(2)对于任意一个类,都需要由加载它的类加载器和这个类本身一同确立其在java虚拟机的唯一性,每一个类加载器都拥有一个独立的类名称空间,不同的类加载器加载出来的类实不相等的。

(3)双亲委派模型

三种类加载器:

1)启动类加载器:加载<JAVA_HOME>\lib目录中的类

2)扩展类加载器:加载<JAVA_HOME>\lib\ext目录下的

3)应用程序加载器:加载用户路径上的类

这些类加载器之间相互配合

双亲委派模型要求除了顶层的启动类加载器外,其余的类加载器都应该有自己的父类加载器,这里的父子关系由组合实现。

工作过程:一个类加载器收到类加载的请求时不是先自己加载,而是将其交由其父类进行加载,当父类无法加载时再交由自己加载,每一层都是如此。

优点:java类随着他的类加载器有了层级关系,如加载java.lang.Object类时所用的类加载器加载出来的都是相同的

 
   

第八章 虚拟机字节码执行引擎

第十二章 Java内存模型与线程

(1)Java内存模型

1)主内存与工作内存:

所有的内存模型都存储在主内存中,每条线程都有自己的工作内存,工作内存中保存了被该线程使用到的变量的主内存副本拷贝,线程对变量的所有操作都必须在工作内存中进行,而不能直接读写主内存中的变量。不同的线程之间也无法直接访问对方工作内存中的变量,线程间变量值的传递只能主内存来完成

2)内存间交互操作

(2)内存间原子操作:lock、unlock、read、load、use、assign、store、write

如果把一个变量从主内存复制到工作内存就要顺序执行read和load操作,如果从工作内存复制到主内存也要顺序执行store和write操作。

(3)Volatile变量

Volatile变量两个特性:可见性、禁止指令重排序优化

不能保证原子性的场景:

1)运算结果依赖于当前值

2)变量需要与其他状态变量共同参与不变约束

(4)Java线程优先级不太靠谱:

1)依赖于操作系统对线程优先级的支持

2)优先级可能被系统改变

(5)状态转换

1)新建

2)运行

3)无限期等待:无参数的wait

4)限期等待:有参数的wait、sleep

5)阻塞:等锁

6)结束

第十三章

时间: 2024-08-24 08:07:43

JVM总结的相关文章

JVM原理讲解和调优

一.什么是JVM JVM是Java Virtual Machine(Java虚拟机)的缩写,JVM是一种用于计算设备的规范,它是一个虚构出来的计算机,是通过在实际的计算机上仿真模拟各种计算机功能来实现的. Java语言的一个非常重要的特点就是与平台的无关性.而使用Java虚拟机是实现这一特点的关键.一般的高级语言如果要在不同的平台上运行,至少需要编译成不同的目标代码.而引入Java语言虚拟机后,Java语言在不同平台上运行时不需要重新编译.Java语言使用Java虚拟机屏蔽了与具体平台相关的信息

jvm系列(一):java类的加载机制

java类的加载机制 原文:http://www.cnblogs.com/ityouknow/p/5603287.html 1.什么是类的加载 类的加载指的是将类的.class文件中的二进制数据读入到内存中,将其放在运行时数据区的方法区内,然后在堆区创建一个java.lang.Class对象,用来封装类在方法区内的数据结构.类的加载的最终产品是位于堆区中的Class对象,Class对象封装了类在方法区内的数据结构,并且向Java程序员提供了访问方法区内的数据结构的接口. 类加载器并不需要等到某个

Java性能优化之JVM GC(垃圾回收机制)

Java的性能优化,整理出一篇文章,供以后温故知新. JVM GC(垃圾回收机制) 在学习Java GC 之前,我们需要记住一个单词:stop-the-world .它会在任何一种GC算法中发生.stop-the-world 意味着JVM因为需要执行GC而停止了应用程序的执行.当stop-the-world 发生时,除GC所需的线程外,所有的线程都进入等待状态,直到GC任务完成.GC优化很多时候就是减少stop-the-world 的发生. JVM GC回收哪个区域内的垃圾? 需要注意的是,JV

JVM垃圾回收算法

1.堆的分代和区域 (年轻代)Young Generation(eden.s0.s1  space)    Minor GC (老年代)Old Generation (Tenured space)     Major GC|| Full GC (永久代)Permanent Generation (Permanent  space)[方法区(method area)]    Major GC 本地化的String从JDK 7开始就被移除了永久代(Permanent Generation ) JDK

Java 详解 JVM 工作原理和流程

作为一名Java使用者,掌握JVM的体系结构也是必须的.说起Java,人们首先想到的是Java编程语言,然而事实上,Java是一种技术,它由四方面组成:Java编程语言.Java类文件格式.Java虚拟机和Java应用程序接口(JavaAPI).它们的关系如下图所示: 运行期环境代表着Java平台,开发人员编写Java代码(.java文件),然后将之编译成字节码(.class文件),再然后字节码被装入内存,一旦字节码进入虚拟机,它就会被解释器解释执行,或者是被即时代码发生器有选择的转换成机器码执

JVM 什么时候会full gc

除直接调用System.gc外,触发Full GC执行的情况有如下四种.1. 旧生代空间不足旧生代空间只有在新生代对象转入及创建为大对象.大数组时才会出现不足的现象,当执行Full GC后空间仍然不足,则抛出如下错误:java.lang.OutOfMemoryError: Java heap space 为避免以上两种状况引起的FullGC,调优时应尽量做到让对象在Minor GC阶段被回收.让对象在新生代多存活一段时间及不要创建过大的对象及数组.2. Permanet Generation空间

jvm java内存区域的介绍

jvm虚拟机在运行时需要用到的内存区域.广泛一点就是堆和栈,其实不然,堆和栈只是相对比较笼统的说法,真正区分有如下几个 先上图一: 总的就是 java的内存模型 内存模型又分堆内存(heap)和方法区(有时也称为non-heap)和栈 堆又分新生代(Young)和老年代(old/Tenured) 新生代又分默认比例为8:1:1的eden空间.from survivor空间.to survivor空间 当进行垃圾回收时,eden.survivor from 存活得对象会复制到servivor to

JVM Safepoint 安全点

一.什么是安全点: 在可达性分析算法中查找存活的对象,首先要找到哪些是GC Roots: 有两种查找GC Roots的方法: 一种是遍历方法区和栈区来查找(保守式GC): 一种是通过OopMap的数据结构来记录引用的位置(准确式GC),如在类加载过程中,JIT编译过程中,分别记录下 类成员 和 调用栈 中的引用的调用信息.对应OopMap的位置即可作用一个安全点.线程只有到达安全点时才能暂停下来进行可达性分析. OopMap:你可以把oopMap简单理解成是调试信息. 在源代码里面每个变量都是有

关于 JDK jre jvm

JDK 全名是 JAVA development kit  是JAVA语言的软件开发工具 包:是整个JAVA开发的核心,没有JDK的话,无法编译Java程序,如果想只运行Java程序,要确保已安装相应的JRE. JDK包含的基本组件包括: javac – 编译器,将源程序转成字节码: jar – 打包工具,将相关的类文件打包成一个文件: javadoc – 文档生成器,从源码注释中提取文档: jdb – debugger,查错工具: java – 运行编译后的java程序(.class后缀的):

JVM学习(2)——技术文章里常说的堆,栈,堆栈到底是什么,从os的角度总结--转载http://www.cnblogs.com/kubixuesheng/p/5202561.html

转载自---http://www.cnblogs.com/kubixuesheng/p/5202561.html 俗话说,自己写的代码,6个月后也是别人的代码--复习!复习!复习!涉及到的知识点总结如下: 堆栈是栈 JVM栈和本地方法栈划分 Java中的堆,栈和c/c++中的堆,栈 数据结构层面的堆,栈 os层面的堆,栈 JVM的堆,栈和os如何对应 为啥方法的调用需要栈 属于月经问题了,正好碰上有人问我这类比较基础的知识,无奈我自觉回答不是有效果,现在深入浅出的总结下: 前一篇文章总结了:JV