Java虚拟机 - JVM是什么?( 六 )


 
直接内存/堆外内存:不属于JVM运行时数据区的,应用于NIO中,直接内存是跳过了Java堆,来提升内存的访问速度,其实就是使用通道和缓冲区的方式进行IO交互的方式,在操作的过程中如果没有设置这一块的堆空间大小,会引起OOM,可以通过-XX:MaxDirectMemonrySize进行设置,如果不配置默认为最大的堆空间大小 。
 
注:直接内存也会触发GC的 。
 
思考:Java为什么要这样设计JVM?为什么还要区分线程共享数据,和线程独有数据?
 
作者的思考思路,集中式有集中式的好,分布式有分布式的好,具体看其语言定位与发展 。

Java虚拟机 - JVM是什么?

文章插图
 
?
Java虚拟机 - JVM是什么?

文章插图
 
Java运行过程 
Java虚拟机 - JVM是什么?

文章插图
 

Java虚拟机 - JVM是什么?

文章插图
 
?
 
垃圾回收机制 
为什么要进行垃圾回收?垃圾是什么?已经在上面讲了 。
 
如何判定对象是可回收的?
Java虚拟机 - JVM是什么?

文章插图
 

Java虚拟机 - JVM是什么?

文章插图
 
?
 
如同这段代码,在方法内执行完了之后,这个test1对象在内存中则是为null了,因方法结束了,也没有其他引用了,在进行对象的引用查找时,则查找不到任何的引用,所以为null,那么则判定这个对象是不可达的,可以进行回收 。
 
垃圾回收级别:作者将其分为三个级别,初级回收(minor GC),二级回收(major GC),完全回收(Full GC) 。
 
初级回收(minor GC):当有新的对象要进入新生代的Eden区时,Eden区的空间不足以存放这个对象,则发生初级回收,而活跃的对象会先存放到新生代的sv区域,并记录年龄+1,当达到阈值(默认15)时就进入老年代 。
 
二级回收(major GC):新生代对象达到阈值或新生代的eden区无法装入大对象时也会进入老年代,但老年代的空间不足以存放这个对象,则会二级回收 。
 
完全回收(Full GC):就是当老年代的空间不足以存放新对象时或永久代的内存不足以存放内容时等 。
 
那么完全回收和二级回收的区别在哪里?
 
JVM是有自动调节功能的,会根据程序在运行中进行调节的,所以何时触发完全回收,那么具体要看JVM的策略,但如果进行了完全回收之后还是出现空间不足以存放,那么则会出现OOM 。
 
算法 
主要说几个主流的垃圾回收算法的思想 。
 
引用计数算法:计数器计算引用的次数,达到阈值就进入老年代,次数为0,则进行回收,对资源消耗严重,每次引用都要进行计算,但精确 。
 
标记清除算法:分为标记和清除阶段,对标记的对象进行清除,清除后导致内存空间不连续,因而产生空间碎片 。
 
对象何时标记清除?
 
就是一个树状结构,根节点向下查找是否可以查找到这个对象,查找不到的对象,则标记清除 。
 
复制算法:将内存区域分为两块,假设现在在使用A区域,这时要进行垃圾回收,把A区域正在使用的对象复制到B区域去,清除A区域所有对象,反复的如此进行,完成垃圾收集 。
 
复制算法:将内存区域分为两块,假设现在在使用A区域,这时要进行垃圾回收,把A区域正在使用的对象复制到B区域去,清除A区域所有对象,反复的如此进行,完成垃圾收集,主要用于新生代 。
 
标记压缩算法:将存活的对象进行压缩,放到一个区域后,在进行垃圾回收,就是结合了标记清除算法和复制算法,主要用于老年代 。
 
为什么复制算法和标记压缩算法主要的应用地方不一致?
 
新生代GC频繁,老年代对象大多数都是稳定的状态,对象多、耗时长 。
 
分代算法:按照对应的策略将内存分为N块区域,根据策略的规定将不同的对象放入不同的区域,控制回收的空间,而不是每次都针对整个空间进行回收,减少GC停顿时间 。
 
如:有个城市是这样规划的女孩子做针线活比较厉害,则把女孩子放到针线区,男孩子力气比较大则放到搬运区,小孩子喜欢玩,放到游乐区,游乐区的人慢慢多了,那么就只对游乐区进行人行疏导,而不需要整个城市都需要进行疏导,对游乐区进行疏导的时候也不会影响到别的区的运行 。


推荐阅读