南昌网站seo外包服务,帮别人做ppt挣钱的网站,湖北省建设工程质量安全监督网站,软件开发项目流程1. 什么是垃圾回收机制#xff1f; 垃圾收集 Garbage Collection 通常被称为“GC”#xff0c;它诞生于1960年 MIT 的 Lisp 语言#xff0c;经过半个多世纪#xff0c;目前已经十分成熟了。 jvm 中#xff0c;程序计数器、虚拟机栈、本地方法栈都是随线程而生随线程而灭 垃圾收集 Garbage Collection 通常被称为“GC”它诞生于1960年 MIT 的 Lisp 语言经过半个多世纪目前已经十分成熟了。 jvm 中程序计数器、虚拟机栈、本地方法栈都是随线程而生随线程而灭栈帧随着方法的进入和退出做入栈和出栈操作实现了自动的内存清理因此我们的内存垃圾回收主要集中于 java 堆和方法区中在程序运行期间这部分内存的分配和使用都是动态的。
2. 那种对象会被回收
判断对象是否存活一般有两种方式
引用计数每个对象有一个引用计数属性新增一个引用时计数加1引用释放时计数减1计数为0时可以回收。此方法简单无法解决对象相互循环引用的问题。可达性分析Reachability Analysis从GC Roots开始向下搜索搜索所走过的路径称为引用链。当一个对象到GC Roots没有任何引用链相连时则证明此对象是不可用的。不可达对象。在Java语言中GC Roots包括 虚拟机栈中引用的对象。方法区中类静态属性实体引用的对象。方法区中常量引用的对象。本地方法栈中JNI引用的对象。
3. 垃圾回收有哪些算法 “标记-清除”Mark-Sweep算法 如它的名字一样算法分为“标记”和“清除”两个阶段首先标记出所有需要回收的对象在标记完成后统一回收掉所有被标记的对象。之所以说它是最基础的收集算法是因为后续的收集算法都是基于这种思路并对其缺点进行改进而得到的。缺点它的主要缺点有两个 一个是效率问题标记和清除过程的效率都不高另外一个是空间问题标记清除之后会产生大量不连续的内存碎片空间碎片太多可能会导致当程序在以后的运行过程中需要分配较大对象时无法找到足够的连续内存而不得不提前触发另一次垃圾收集动作。 复制算法 “复制”Copying的收集算法它将可用内存按容量划分为大小相等的两块每次只使用其中的一块。当这一块的内存用完了就将还存活着的对象复制到另外一块上面然后再把已使用过的内存空间一次清理掉。这样使得每次都是对其中的一块进行内存回收内存分配时也就不用考虑内存碎片等复杂情况只要移动堆顶指针按顺序分配内存即可实现简单运行高效。只是这种算法的代价是将内存缩小为原来的一半持续复制长生存期的对象则导致效率降低。 标记-压缩算法 复制收集算法在对象存活率较高时就要执行较多的复制操作效率将会变低。更关键的是如果不想浪费50%的空间就需要有额外的空间进行分配担保以应对被使用的内存中所有对象都100%存活的极端情况所以在老年代一般不能直接选用这种算法。根据老年代的特点有人提出了另外一种“标记-整理”Mark-Compact算法标记过程仍然与“标记-清除”算法一样但后续步骤不是直接对可回收对象进行清理而是让所有存活的对象都向一端移动然后直接清理掉端边界以外的内存 分代收集算法 GC分代的基本假设绝大部分对象的生命周期都非常短暂存活时间短。“分代收集”Generational Collection算法把Java堆分为新生代和老年代这样就可以根据各个年代的特点采用最适当的收集算法。在新生代中每次垃圾收集时都发现有大批对象死去只有少量存活那就选用复制算法只需要付出少量存活对象的复制成本就可以完成收集。而老年代中因为对象存活率高、没有额外空间对它进行分配担保就必须使用“标记-清理”或“标记-整理”算法来进行回收。
新生代和老年代有什么区别? 年轻代Young Generation 所有新生成的对象首先都是放在年轻代的。年轻代的目标就是尽可能快速的收集掉那些生命周期短的对象。新生代内存按照8:1:1的比例分为一个eden区和两个survivor(survivor0,survivor1)区。一个Eden区两个 Survivor区(一般而言)。大部分对象在Eden区中生成。回收时先将eden区存活对象复制到一个survivor0区然后清空eden区当这个survivor0区也存放满了时则将eden区和survivor0区存活对象复制到另一个survivor1区然后清空eden和这个survivor0区此时survivor0区是空的然后将survivor0区和survivor1区交换即保持survivor1区为空 如此往复。当survivor1区不足以存放 eden和survivor0的存活对象时就将存活对象直接存放到老年代。若是老年代也满了就会触发一次Full GC也就是新生代、老年代都进行回收新生代发生的GC也叫做Minor GCMinorGC发生频率比较高(不一定等Eden区满了才触发) 年老代Old Generation 在年轻代中经历了N次垃圾回收后仍然存活的对象就会被放到年老代中。因此可以认为年老代中存放的都是一些生命周期较长的对象。内存比新生代也大很多(大概比例是2:1)当老年代内存满时触发Major GC即Full GCFull GC发生频率比较低老年代对象存活时间比较长存活率标记高。 永久代Permanent Generation用于存放静态文件如Java类、方法等。永久代对垃圾回收没有显著影响但是有些应用可能动态生成或者调用一些class例如Hibernate 等在这种时候需要设置一个比较大的永久代空间来存放这些运行过程中新增的类。