深入理解Java虚拟机--初探
Posted 当以乐
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了深入理解Java虚拟机--初探相关的知识,希望对你有一定的参考价值。
1.走近Java
这一章主要介绍了Java的发展历史,JVM种类,最后的编译OpenJDK.我编译的OpenJDK10.
2.Java内存区域与内存溢出异常
2.1 JVM中几个数据区
方法区,虚拟机栈,本地方法栈,堆,程序计数器.
2.2.1 程序计数器
是一块较小的内存空间,它可以看作是当前线程所执行的字节码的行号指示器.唯一不会发生OOM的区域.
2.2.2 Java虚拟机栈
与程序计数器一样,Java虚拟机栈也是线程私有的,它的生命周期与线程一样.每个方法在执行的同时都会创建
一个栈帧用于存储局部变量表,操作数栈,动态链接,方法出口等信息.每个方法从调用直至执行完成的过程,就对应着一个
栈帧在虚拟机栈中入栈到出栈的过程.
2.2.3 本地方法栈
本地方法栈与虚拟机栈所发挥的作用是非常相似的,它们之间的区别不过是虚拟机栈为虚拟机执行Java方法服务,
而本地方法栈则为虚拟机使用的Native方法服务.HotSopt虚拟机将本地方法栈和虚拟机栈合二为一.
2.2.4 Java堆
Java堆是被所有线程共享的一块内存区域,在虚拟机启动时创建.此内存区域的唯一目的就是存放对象实例,几乎所有
的对象实例都在这里分配内存.基于分代收集算法,Java堆还可以细分为:新生代和老年代.新生代又可以分为Eden空间,From Survivor空间,
To Survivor空间等.
2.2.5 方法区
方法区与Java堆一样,是各个线程共享的内存区域,它用于存储已经被虚拟机加载的类信息,常量,静态变量,即时编译器
编译后的代码等数据.
2.2.6 运行时常量池
运行时常量池是方法区的一部分.Class文件中除了有类的版本,字段,方法,接口等描述信息外,还有一项信息是常量,用于
存放编译期生成的各种字面量和符号引用,这部分内容将会在类加载后进入方法区的运行时常量池中存放.
2.2.7 直接内存
就是常说的堆外内存,通过NIO引入.
3. 垃圾收集器与内存分配策略
3.1 垃圾收集
那些内存需要回收?
什么时候回收?
如何回收?
.3.2 对象死亡判断
3.2.1 引用计数算法
给对象中添加一个引用计数器,每当有一个地方引用它时,就加一,当引用失效时就减1,任何时刻计数器为0的对象就是
不可能再被使用的.
3.2.2 可达性分析算法
通过一系列的称为 "GC Roots" 的对象作为起始点,从这些节点开始向下搜索,搜索所走过的路径称为引用链,当一个对象到GC Roots 没有任何引用链相连时,则证明此对象是不可用的.
3.2.3 再谈引用
强引用: 指代码中普遍存在的 类似 Object o = new Object(); 只要强引用还在,垃圾收集器永远不会回收掉被引用的对象
软引用: 用来描述一些还有用但不是必须的对象.
弱引用: 用来描述非必须对象.
虚引用: 最弱的引用关系.
3.2.4 生存还是死亡
一个对象死亡要经过两次标记:如果对象在进行可达性分析后发现没有与GC Roots相连接的引用链,那它将会被第一次标记并且进行一次筛选,筛选的条件是此对象是否有必要执行finalize()方法.当对象没有覆盖finalize()方法或者finalize()方法已经被调用过了,这都会被视为没有必要执行,否则这个对象将被放在一个F-Queue队列中.等待执行finalize()方法,如何能拯救自己即建立引用链,则不会被二次标记.
3.2.5 回收方法区
即对HotSpot中的永久代进行回收只要是废弃的常量和无用的类.
以上是关于深入理解Java虚拟机--初探的主要内容,如果未能解决你的问题,请参考以下文章