在实际开发中我们会用到finalize么?
Java为什么弃用 finalize() 方法?
尽量避免使用 因为用了也不一定会被回收
你创建了一个类并且小心翼翼的写了finalize()方法。一些人来extend了你的类,但是在子类中的finalize()块中没有调用super.finalize()方法。然后超类中finalize()方法将永远都不会被调用。
jvm如何判断对象是否是垃圾?
1.引用计数算法 不能解决循环引用
2.可达性分析算法: 扫面堆当中的对象,由GC Roots对象作为起始点 向下搜索没有与其相连的对象就会被当作垃圾 并且回收
GC Root 一般是什么对象?(不会被回收的对象)
- 虚拟机栈(栈中的本地变量表)中引用的对象 JVM Stack 线程池变量
- 方法区中类静态引用的对象 static references in method area 静态变量
- 方法区中常量引用的对象 run-time constant pool 常量池
- 本地方法栈JNI引用的对象
四种垃圾回收算法
1.标记-清除 :找到可回收垃圾 把其变成未使用的
速度快但是 产生大量碎片当再有对象放入内存 因为没有连续的地址可用 就会触发下一次垃圾回收操作2.复制 需要两倍的内存空间 浪费空间
把内存分为两半,每次只是用其中的一份,当这一份用完了,把还存活的对象复制到另一块上面,把已经用过的内存空间一次清理掉。然后向另一块开始分。
- 把from区中的不可回收对象复制到to区 再清空from区中的垃圾 再交换from区和to区 没有碎片
优点:没有碎片
浪费空间 因为它每次都只用一半 所以我们要两倍的内存
3.标记-整理 效率低 比复制线性时间大很多
让所有的存活对象向一段移动(多线程移动要进行线程同步 不能这面移动 那面还向里添加东西) 然后把清理掉端边界以外的内存 移动会带来大量的时间消耗 但是没有产生碎片
4.分代算法
根据对象存活周期不同,将内存划分几块。把java堆分成老年代和新生代,根据代的不同定制不同的方法。 - 新生代的对象的特点是:垃圾回收时候会有大量对象死去,只有少量存活,所以试用复制,因为复制的都是存活对象,省时间。新生代都使用复制算法
- 老年代的特点就是:对象存活率高 试用标记清除或者标记清理
程序运行的时候堆内存中(按逻辑)分区都有哪些?
堆中分新生代和老年代 比例 1:3
新生代又分两类 三个区域edan: survivor :survivor 8:1:1
YGC的流程是什么?什么时候进入老年代?年轻代采用什么算法?
- 每当有一个new 的对象会先到edan中分配内存 只有edan都不够容纳当前对象时直接存入到老年代
新生代垃圾回收称为YGC =MinorGC
10%的对象存活 90%的对象被回收
第一次YGC:把存活的对象复制到survivor0后 直接清理eden的所有垃圾
第二次YGC:目前eden survivor1都有对象 这两个区的存活对象都复制到survivor1
然后清空Eden+s0–>1
再次:Eden+s1–>s0
年轻代Eden空间耗尽的时候触发ygc
当一个对象在新生代中年龄一般垃圾回收器超过15 CMS超过6
s区已经装不下了就到老年代
当老年代都满了就触发FullGC=MajorGC会产生STW停顿现象
你new一个对象 具体内存分配在哪里
垃圾回收器 通常是这3中搭配
- Serial 年轻代 单线程串行回收 使用复制算法 简单高效 适合client模式 也可以和cms搭配使用
每次回收的时候必须要让所有业务线程停止 stop the world STW 执行回收这个线程 类似妈妈这个线程打扫屋子让所有的业务线程不要再扔纸
- ParNew 年轻代 并行回收 多个线程(妈妈)同时进行垃圾回收 和CMS配合使用 适合server模式
- Paraller Scavenge 新生代收集器 注重高吞吐量而不是线程停顿
老年代
- SerialOld收集器 使用 标记-整理
- ParalleOld收集器 标记-整理 但是线程切换的时候cpu也要花费
- CMS 搭配 parNew
1.Concurrrent(并发) Mark Sweep并发的 垃圾回收和应用程序同时运行
降低停顿STW的时间 基于标记-清除的(碎片化)
1.1Paraller (并行)多个线程并行清理 但是所有的用户线程还在等待
2.CMS过程 - 初始标记 需要STW但是很快 标记GCROOTS直接关联的对象
- 并发标记 最耗时的操作 就是可达性算法 沿着刚才标记的对象找垃圾
- 重新标记 需要STW 修正并发标记阶段 因为应用程序还在运行 有些标记已经有了改动 我们要重新更新记录
- 并发清理 以上不和根相连的就被删除了
CMS的缺点是他的碎片化 最后会被SerialOLD去回收
不分代
- jdk1.9默认 G1
- ZGC
- JDK 1.8默认的垃圾回收期时PS (Paraller Scavenge) 和 paralle Old 多个人来请
-