jvm内存数据管理及GC算法的

java内存管理之数据区域划分

请输入图片地址

运行时数据区域 java虚拟机在程序运行中会将内存划分为不同的数据区域,这些区域有着不同的用处和不同的生存时间

java对象访问定位方式

java通过在栈上的reference数据(执行对象的指针)来操作堆上的具体对象

java对象存活判断

java引用类型

java在对象回收过程中会进行两次标记,对象失去链接–>标记–>是否拯救自己(finalsize or not)对象重写建立引用–>没有建立新引用的对象进行二次标记 –> GC回收

回收方法区-回收类-1该类所有的实例都已经被回收 2加载该类的classLocader被回收3该类class对象没有在任何地方被引用,无法在任何地方通过反射访问该类方法。-Xnoclassgc参数进行控制,大量使用反射,动态代理的框架,地方都应该配置该参数

jvm内存回收

方法区回收 方法区,HotSpot也叫做永久代,通常这个区域回收的性价比比较低,这个区域回收的内容主要是废弃常量无用的类 方法区判断可以回收的方法:

  1. 该类所有的实例都已经被回收
  2. 加载该类的classLocader被回收
  3. 该类class对象没有在任何地方被引用,无法在任何地方通过反射访问该类方法。

垃圾回收算法

枚举根节点 可达性分析应建立在能确保一致性的快照中进行,确保对象引用关系不会在变化,通常会采用Stop The world操作,停止所有执行线程。而GC停顿时长是敏感的,在HotSpot中使用OopMap数据结构在类加载时就计算对象内的所有类型数据的偏移量,记录栈和寄存器引用。从而实现准确,快速的GS Roots节点的获取

安全点 当JVM进行GC时,要保证所有执行执行线程都处于一个安全的位置,这个位置叫做安全点,而为了保证所有执行线程处于安全点有两种方式 1 抢断式中断 jvmGC时停止所有执行线程,如果发现有执行线程不在安全点上,恢复其线程,到达安全点。2 主动式中断 设置一个标志,执行线程主动轮询这个标志,如果标志位置和安全点位置重合,则挂起线程

安全区域 安全点的设置会导致不太长时间就会上面一系列操作,效率会很低。安全区域指一段代码片段之中,引用关系不会发生变化,这个区域任何时候GC都是安全的。当线程进入安全区域是标记自己进入,当jvmGC时,不用关心这个线程;线程当离开安全区域时,检查GC是否完成,未完成则等待释放信号

内存分配,回收策略

优先分配到Eden区 大多数情况对象优先分配到Eden区,当Eden内存不够时,jvm进行minor GC(发生在新生代的垃圾回收动作,很频繁)

大对象直接进入老年代 当创建对象时,需要大量连续内存空间的对象,比如大字符串或大数组

长期存活对象直接进入老年代 jvm会采用分代收集思想管理内存,jvm为每个创建的对象设定一个Age计数器。如果对象在eden出生,在经过第一次GC存活,并且进入survivor区,那么age加1,在survivor区以后每一次minor GC后存活,age加1;当达到一定age进入老年代

动态对象年龄判断 当survivor中相同年龄所有对象大小总和大于Survivor空间一半,大于该年龄的对象进入老年代

空间分配担保 Minor GC前jvm会判断老年代最大可用连续空间是否大于新生代所有对象总空间,如果条件成立,那么minor GC时安全的;如果不成立,查看允许担保配置HandlePromotionFailure值是否允许担保失败,如果没有配置则进行FullGC(发生在老年代的GC,会比minor GC 慢10倍以上);如果有配置检查老年代最大可用连续空间是否大于历次晋升老年代对象平均大小,如果大于则进行minor GC,否则full GC