JVM基本概念、垃圾回收机制(一)

1.什么是JVM?3W1H
   定义:
    jvm是一个虚构出来的计算机,是在实际的计算机上仿真模拟出各种计算机的功能来实现的。
   有什么用:
    Java语言最重要的特点就是跨平台运行,Java程序的跨平台特性主要是指字节码文件可以在任何具有Java虚拟机的计算机或者电子设备上运行,使用JVM就是为了支持与操作系统无关,实现跨平台。
   JVM内存区域划分:
    类装载器子系统、运行时数据区、执行引擎。
    (一)类装载器子系统:
     负责加载程序中的类型(类和接口)、并赋予唯一名称。JVM的两种类装载器包括:启动类装载器和用户自定义类装载器,启动类装载器是JVM实现的一部分,用户自定义类装载器则是Java程序的一部分,必须是ClassLoader类的子类。
    (二)执行引擎:
     作用:执行字节码和本地方法。
     执行引擎分类:1.最简单的是一次性解释字节码。
             2.即时编译器:更快、更消耗内存,第一次被执行的字节码会被编译成本地机器代码。编译出的本地机器代码会被缓存,当方法以后被调用的时候可以重用。
             3.自适应优化器:在这种方法里,虚拟机开始的时候解释字节码,但是会监视运行中程序的活动,并且记录下使用 最频繁 的 代码段。程序运行的时候,虚拟机只把那些活动最频繁的代码编译成本地代码,其他的代码由于使用得不是很频繁,继续保留为字节码,由虚拟机继续解释它们。 一个自适应的优化器可以使得Java虚拟机在80%~90%的时间里执行被优化过的本地代码,而只需要编译10%~20%的对性能有影响的代码。
    (三)运行时数据区:包括:方法区,堆,Java栈,PC寄存器,本地方法栈。
JVM的垃圾回收机制:
    堆内存分为新生代(亚当和夏娃)和老年代
 
    新创建的对象
      首先 新生代 亚当区
      ——————(一次)minerGC回收
     新生代 夏娃区
      ——————(多次)minerGC回收
     老年代
 
     
    亚当满了——————>夏娃区满了——————>另一个夏娃区满了—————>之前的夏娃会到老年代
 
 
    年轻代 复制算法:
     内存分为两块,每次占用一块。
     这一块用完,就把还活着的复制到另一块。
     
    新创建的对象
     首先 新生代 亚当区、名为From的夏娃区
       ——————————minerGC回收
       新时代 亚当区——>名为To的夏娃区
       名为To的夏娃区——(年龄ok)——老年代
       此时,eden区和名为from的survior区已经被清空,from和to会交换他们的角色,也就是新的to就是上次GC前的from
 
   
   
        
    Minor GC:从年轻代回收内存  
    Full GC:是清理整个堆空间包括年轻代和老年代。
 
 
 
    什么时候触发:
      minerGC:亚当区没有内存空间时触发
      FullGC:老年代没有足够的空间
      
  
  
  
  
    在发生MinorGC之前,虚拟机会先检查老年代最大可利用的连续空间是否大于新生代所有对象的总空间。
    如果大于则进行Minor GC,如果小于则看HandlePromotionFailure设置是否是允许担保失败(不允许则直接FullGC)
    如果允许,那么会继续检查老年代最大可利用的连续空间是否大于历次晋升到老年代对象的平均大小,如果大于
    则尝试minor gc (如果尝试失败也会触发Full GC),如果小于则进行Full GC。
    但是,具体什么时候执行,这个是由系统来进行决定的,是无法预测的。
   
   
   
   
    对什么东西:
    主要根据可达性分析算法,如果一个对象不可达,那么就是可以回收的,如果一个对象可达,那么这个对象就不可以回收,
    对于可达性分析算法,它是通过一系列称为“GC Roots”的对象最为起始点,当一个对象GC Roots没有任何引用链相接的时候,
    那么这个对象就是不可达,就可以被回收。
 
 
 
    做了什么事情:
    主要做了清理对象,整理内存的工作。Java堆分为新生代和老年代,采用了不同的回收方式。
    例如新生代采用了复制算法,老年代采用了标记整理法。在新生代中,分为一个ede区域和两个Survior
    区域,真正使用的是一个eden区域,和一个Survior区域,GC的时候,会把存活的对象放入到另一个Survior区域中,
    然后再把这个eden区域和Survior区域清除。那么对于老年代,采用的是标记整理发,首先标记出存活对象,
    然后在移动到一段。这样有利于减少内存碎片。
    标记:标记的过程其实就是,遍历所有gc root 然后将所有gc root 可达的对象标记为存活对象
    清除:清除的过程中将遍历堆中所有的对象,将没有标记的对象全部清除掉
    主要缺点:标记和清除过程效率不高,标记清除之后会产生大量不连续的内存碎片
     但是,老年代中因为对象存活率高,没有额外空间对他进行分配担保,就必须使用标记整理算法
    标记整理算法 标记操作和“标记-清除”算法一致,后续操作不只是直接清理对象,而是在清理
    无用对象完成后让所有存活的对象都向一段移动,并更新其引用对象的指针
    主要缺点:在标记清除的基础上还需要进行对象的移动,成本相对比较高,成本相对较高,好处是不会产生内存碎片。

猜你喜欢

转载自www.cnblogs.com/wzdnwyyu/p/11163027.html