垃圾回收机制
内存溢出与内存泄露
内存溢出:是程序启动需要10M,但是内存只分配了5M,启动都启动不了
内存泄露:内存没及时释放,下一个线程要用,重启可以解决,这时就要考虑对象的回收
手动回收
package com.fly.jvmDemo;
/**
* @Title: 垃圾回收机制
* @author: Fly
* @date: 2020/3/26 - 6:05
*/
public class JvmDemo1 {
public static void main(String[] args) {
JvmDemo1 jvmDemo1 = new JvmDemo1();
jvmDemo1=null;//标识不可达
//手动调用gc,其实在通知gc去回收,不百分百立马回收
System.gc();
}
//finally 和 finalize 区别
@Override
protected void finalize() throws Throwable{
//当垃圾回收机制回收的时候,就会调用的方法
System.out.println("对象要被回收啦!!");
}
}
垃圾回收机制算法
1.引用计数法(淘汰)
- 给对象添加一个引用计数器,每当有一个地方引用它时,计数器值就会+1;
-
- 当引用失效时,计数器值就减1;
- 任何时刻计数器都为0的对象就是不再被使用,垃圾回收器将回收该对象使用的内存
2.标记清除算法
缺点:效率低;清除之后会产生大量碎片
3.复制算法(新生代的S0和S1)
- eden区引用到一定数量时,会到S0或S1区
- S0区还在使用的对象,会被复制算法to复制到S1区,没有被使用的对象就会被回收,S0这时为空
- 这时eden再进来一个对象,会现进去S1区
- S1区还在使用的对象,会被复制到S0区,没有被使用的对象就会被回收,S1区这时为空
4.标记压缩(标记清除的升级版:老年代)
清除之后会不会产生大量碎片
5.分代收集算法(新生代,老年代)
6.分区算法(JDK1.7)
GC经常回收为什么不好?
GC在回收时候,其他线程全部等待.
垃圾回收器
串行回收(Serial Collector)
- 单线程(单核回收)
- “-XX:+UseSerialGC”
- 效率低
并行回收
- 多线程回收(多核回收)
- ParNew回收器是一个工作在新生代的垃圾收集器,"-XX:+UseParNewGC"
- ParallelGC:新生代
- “-XX:+UseParallelGC”:说说有哪些调优参数
- ParallelOldGC:老年代
- “-XX:+UseParallelOldGC”:说说有哪些调优参数
- "-XX:+ParallelCThread:设置垃圾收集时的线程数量
CMS回收(Concurrent Mark Sweep)
- 以最短时间停顿收集
串行回收器Tomcat参数调优
- 服务器是单核的
- “-XX:+UseSerialGC”:调优参数
- 堆内存-Xmx:32m,-Xms:32
GC6次,吞吐量314
堆内存-Xmx:512m,-Xms:32
GC2次,吞吐量349
堆内存-Xmx:512m,-Xms:256
GC0次,吞吐量416
并行回收器Tomcat参数调优
GC0次,吞吐量589(并行比串行块)
GC0次,吞吐量649(并行比串行块)