频繁发生fullgc的原因和定位思路

向一个集合里添加很多数据这种OOM的例子就不说了

1.内存飙升频繁FullGC

内存飙升频繁FullGC又没有发生OOM很明显这个对象在年轻代没有被销毁进入了老年代,
至于为什么不会OOM是因为这个对象的生命周期很短比如5秒所以每次fullgc都能回收掉
导致对象没有在年轻代被回收的原因有以下情况该
1.对象的内存比年轻代还大,比如对象100兆,年轻代50兆直接放入老年代
2.触发了动态年龄判断放入老年代
3.触发了空间担保机制放入老年代
4.高并发方法执行慢,产生的内存多年轻代装不下此时进行进行youngGC也回收不掉,
是因为方法没有结束是不能回收方法内的gcroot的,那么此时在进来10个个线程这些线程
产生的数据年轻代装不下那么就放入老年代里,当5秒过后这些方法才执行完那么此时的方法
才出栈如果老年代满了是可以回收掉这些垃圾的,如果并发量在高些就会发生OOM,
比如老年代存放的都是2秒后方法才结束的对象当内存满了进行fullgc是回收不掉的因为这些对象
2秒后才能成为垃圾

4核8线程
-Dfile.encoding=utf-8
-Xms400m
-Xmx400m
-XX:MetaspaceSize=512m
-XX:SurvivorRatio=8
-Xss512k
-XX:+HeapDumpOnOutOfMemoryError
-XX:HeapDumpPath=f:/dev/
-XX:+PrintGCDetails
-XX:+PrintGCDateStamps
-Xloggc:f:/dev/gc.log

情况一 方法执行很快产生的垃圾处理情况
并发量中等但是方法产生的垃圾小
[8并发]:[单个方法耗时40毫秒占用1m]:[是否fullgc false]
并发量中方法产生的垃圾大
[8并发]:[单个方法耗时70毫秒占用2m]:[是否fullgc true]
并发量高但是方法产生的垃圾小
[高并发]:[单个方法耗时40毫秒占用1m]:[是否fullgc true]

情况二 方法执行很慢产生的垃圾处理情况
并发量中但是方法产生的垃小
[8并发]:[单个方法耗时1000毫秒占用1m]:[是否fullgc false]
并发量高但是方法产生的垃小
[高并发]:[单个方法耗时1000毫秒占用1m]:[是否fullgc true]
并发量中方法产生的垃大
[8并发]:[单个方法耗时1000毫秒占用2m]:[是否fullgc true]
并发量高方法产生的垃大
[高并发]:[单个方法耗时1000毫秒占用2m]:[OOM]
总结:方法执行慢并且产生的垃圾多那么就很容易频繁fullgc和oom,而高并发就容易让这个条件满足

2.解决高并发并发fullgc

采用线程池控制并发数量,

没控制并发前

控制并发后

方式一线程池

@RestController
@RequestMapping("/userOrder")
public class UserOrderController {
    ExecutorService executorService = Executors.newFixedThreadPool(2);
    @RequestMapping("/hello")
    public String hello(){
        executorService.submit(()->{
            //模拟service方法产生100的垃圾,2个线程最高200m垃圾
            B b = new B(1);
        });
        return "success";
    }
}

方式二Semaphore (推荐)

@RestController
@RequestMapping("/userOrder")
public class UserOrderController {   
    static Semaphore semaphore = new Semaphore(10,true);
    @RequestMapping("/hello")
    public String hello(){
        try{
            //请求一个信号
            semaphore.acquire();
            B b = new B(1);
            //释放一个信号
            semaphore.release();
        }catch (Exception e){
            e.printStackTrace();
        }
        return "success";
    }
}

你可能感兴趣的:(java面试,spring,jvm,java,开发语言)