网站开发好不好,怎样做当地网站推广,北京手机网站开发费用,东莞网络排名优化价格垃圾收集 (Garbage Collection,GC)
垃圾收集主要是针对堆和方法区进行。程序计数器、虚拟机栈和本地方法栈这三个区域属于线程私有的#xff0c;只存在于线程的生命周期内#xff0c;线程结束之后就会消失#xff0c;因此不需要对这三个区域进行垃圾回收。
判断一个对象是…垃圾收集 (Garbage Collection,GC)
垃圾收集主要是针对堆和方法区进行。程序计数器、虚拟机栈和本地方法栈这三个区域属于线程私有的只存在于线程的生命周期内线程结束之后就会消失因此不需要对这三个区域进行垃圾回收。
判断一个对象是否可被回收
如果一个或多个对象没有任何的引用指向它了那么这个对象现在就是垃圾如果定位了垃圾则有可能会被垃圾回收器回收。
如果要定位什么是垃圾有两种方式来确定第一个是引用计数法第二个是可达性分析算法
引用计数算法
为对象添加一个引用计数器当对象增加一个引用时计数器加 1引用失效时计数器减 1。引用计数为 0 的对象可被回收。
在两个对象出现循环引用的情况下此时引用计数器永远不为 0导致无法对它们进行回收。正是因为循环引用的存在因此 Java 虚拟机不使用引用计数算法。 可达性分析算法
通过判断对象的引用链是否可达来决定对象是否可以被回收。
以 GC Roots 为起始点进行搜索可达的对象都是存活的不可达的对象可被回收。 方法区的回收
因为方法区主要存放永久代对象而永久代对象的回收率比新生代低很多所以在方法区上进行回收性价比不高。
主要是对常量池的回收和对类的卸载。
为了避免内存溢出在大量使用反射和动态代理的场景都需要虚拟机具备类卸载功能。
类的卸载条件很多需要满足以下三个条件并且满足了条件也不一定会被卸载
该类所有的实例都已经被回收此时堆中不存在该类的任何实例。加载该类的 ClassLoader 已经被回收。该类对应的 Class 对象没有在任何地方被引用也就无法在任何地方通过反射访问该类方法。
finalize()
类似 C 的析构函数注意只是类似C 析构函数调用确定而 finalize() 方法是不确定的用于关闭外部资源。但是 try-finally 等方式可以做得更好并且该方法运行代价很高不确定性大无法保证各个对象的调用顺序因此最好不要使用。
当垃圾回收器要宣告一个对象死亡时至少要经历两次标记过程。
如果对象在进行可达性分析以后没有与GC Root 直接相连接的引用量就会被第一次标记并且判断是否执行 finalize() 方法
如果这个对象覆盖了 finalize() 方法并且未被引用就会被放置于 F-Queue 队列稍后由虚拟机创建的一个低优先级的 finalize() 线程去执行触发 finalize() 方法在该方法中让对象重新被引用从而实现自救。但是该线程的优先级比较低执行过程随时可能会被终止。此外自救只能进行一次如果回收的对象之前调用了 finalize() 方法自救后面回收时不会再调用该方法。 “标记-清除” 算法
标记清除算法是将垃圾回收分为2个阶段分别是标记和清除。
在标记阶段从根集合进行扫描会检查每个对象是否为活动对象如果是活动对象则程序会在对象头部打上标记可达性算法进行标记。
在清除阶段会进行对象回收并取消标志位另外还会判断回收后的分块与前一个空闲分块是否连续若连续会合并这两个分块。回收对象就是把对象作为分块连接到被称为 “空闲链表” 的单向链表之后进行分配时只需要遍历这个空闲链表就可以找到分块。
在分配时程序会搜索空闲链表寻找空间大于等于新对象大小 size 的块 block。如果它找到的块等于 size会直接返回这个分块如果找到的块大于 size会将块分割成大小为 size 与 (block - size) 的两部分返回大小为 size 的分块并把大小为 (block - size) 的块返回给空闲链表。
优点标记和清除速度较快缺点碎片化较为严重内存不连贯的
”标记-整理“ 算法
标记过程仍然与“标记-清除”算法一样但后续步骤不是直接对可回收对象回收而是让所有存活的对象都向一端移动然后直接清理掉端边界以外的内存。
优点不会产生内存碎片不足需要移动大量对象处理效率比较低。
”复制“ 算法
将内存划分为大小相等的两块每次只使用其中一块当这一块内存用完了就将还存活的对象复制到另一块上面然后再把使用过的内存空间进行一次清理。
主要不足只使用了内存的一半。
现在的商业虚拟机都采用这种收集算法回收新生代但是并不是划分为大小相等的两块而是一块较大的 Eden 空间和两块较小的 Survivor 空间每次使用 Eden 和其中一块 Survivor。在回收时将 Eden 和 Survivor 中还存活着的对象全部复制到另一块 Survivor 上最后清理 Eden 和使用过的那一块 Survivor。
HotSpot 虚拟机的 Eden 和 Survivor 大小比例默认为 8:1保证了内存的利用率达到 90%。如果每次回收有多于 10% 的对象存活那么一块 Survivor 就不够用了此时需要依赖于老年代进行空间分配担保也就是借用老年代的空间存储放不下的对象。
对后面的内容我也是迷迷糊糊的就借用网上大神们的总结的知识点画的思维导图给大家了解一下
概括版视图