Java虚拟机(JVM)详解
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java虚拟机(JVM)详解相关的知识,希望对你有一定的参考价值。
jvm体系结构
1.类装载子系统:装载具有合适名称的类或者接口
2.执行引擎:负责执行包含在已装载类或接口中的指令。
内存模型
每个jvm中都会包含:
方法区(持久代),java堆(heap),java栈(stack),指令计数器(寄存器),本地方法栈。
java堆:保存对象实例。
java栈:保存基本类型,返回结果,非基本类型数据在堆中的指针。
方法区:保存类信息,静态变量,或者是被定义为final的常量。
其中方法区与堆为线程共享。
GC(Garbage Collection)
程序计数器、虚拟机栈、本地方法栈是每个线程私有的内存空间,随线程而生,随线程而亡。例如栈中每一个栈帧中分配多少内存基本上在类结构去诶是哪个下来时就已知了,因此这3个区域的内存分配和回收都是确定的,无需考虑内存回收的问题。
但方法区和堆就不同了,一个接口的多个实现类需要的内存可能不一样,我们只有在程序运行期间才会知道会创建哪些对象,这部分内存的分配和回收都是动态的,GC主要关注的是这部分内存
判断一个对象已死的方法:可达性分析。
所有已生成的对象都是一个称为“GC Roots"的子树,从GC roots开始往下搜索,搜索经过的路径成为引用链。当一个对象到GC roots没有可用引用链时,就称这个对象是不可达的。
内存分配
Java技术体系中所提倡的自动内存管理最终可以归结为自动化的解决2个问题:给对象分配内存以及回收分配给对象的内存。
对象优先在Eden分配
大多数情况下,对象在新生代Eden区分配。当Eden区没有足够的内存时,虚拟机将发起一次Minor GC。
- Minor GC(新生代GC):指发生在新生代的垃圾收集动作,因为Java对象大多都具备朝生夕灭的特性,所以Minor GC发生的非常频繁。
- Full GC/Major GC(老年代GC):指发生在老年代的GC,出现了Major GC,经常会伴随至少一次的Minor GC。
大对象直接进老年代
大对象是指需要大量连续内存空间的Java对象(例如很长的字符串以及数组)。
长期存活的对象将进入老年代
JVM为每个对象定义一个对象年龄计数器。
- 如果对象在Eden出生并经历过第一次Minor GC后仍然存活,并且能够被Survivor容纳,则应该被移动到Survivor空间中,并且年龄对象设置为1;
- 对象在Survivor区中每熬过一次Minor GC,年龄就会增加1岁,当它的年龄增加到一定程度(默认为15岁,可通过参数-XX:MaxTenuringThreshold设置),就会被晋升到老年代中。
- 要注意的是:JVM并不是永远的要求对象的年龄必须达到MaxTenuringThreshold才能晋升老年代,如果在Survivor空间中相同年龄所有对象大小的总和大于Survivor空间的一般,年龄大于等于该年龄的对象就可以直接进入老年代,无需等到MaxTenuringThreshold中要求的年龄。
空间分配担保
- 在发生Minor GC之前,虚拟机会先检查老年代最大可用的连续空间是否大于新生代所有对象总空间,如果这个条件成立,则进行Minor GC是安全的;
- 如果不成立,则虚拟机会查看HandlePromotionFailure设置值是否允许担保失败。如果允许,则急促检查老年代最大可用连续空间是否大于历次晋升到老年代对象的平均大小,如果大于,将尝试着进行一次Minor GC,尽管它是有风险的;
- 如果小于或者HandePromotionFailure设置为不允许冒险,则这时要改为进行一次Full GC.
以上是关于Java虚拟机(JVM)详解的主要内容,如果未能解决你的问题,请参考以下文章