一、误用线程池导致的内存溢出
1、误用固定大小线程池
模拟一个短信发送的场景,创建了一个固定大小的线程池,有两个核心线程,循环不断创建线程,输出send sms,模拟了一个发送超时场景
因为提交超时,所以剩余任务进入了线程池,导致内存溢出
我们再看看newFixedThreadPool的源码,里面的LinkedBlockingQueue<Runnable>是一个无边界的队列,把握不好容易内存溢出。所以建议大家使用的时候创建一个有限制的任务队列。
2、误用带缓存线程池
newCachedThreadPool没有核心线程,全是救急线程,线程数量为整数最大数,如果任务繁多,会创建大量的线程,他也会造成内存溢出
我们让问题在linux上出现,修改系统两个参数,一个是进程最大数,一个是线程最大数
他大约跑了177个线程,出现了报错:不能创建本地线程,可能是因为内存或者资源的限制。这是因为任务数过多,导致队列塞满,内存溢出
二、查询数据量太大导致的内存溢出
这是一个商品的集合
通过一些工具类计算对象大约占用的内存,如果数量多,是比较大的。如果你写了一个findALL方法,在本地测试没有问题,因为本地数据量少,虽然我们平时代码会给findAll加条件,但是有可能条件失效,最稳妥的办法还是加一个limit限制查询条数。
三、动态生成类导致的内存溢出
实际开发中,我们经常会用到一些第三方脚本语言,Groovy语言,代码不断执行脚本
运行1k多次才出现了异常,元空间出现了内存溢出
每次执行脚本都有一个类加载器,而且因为代码中定义的对象为静态对象,生命周期较长
解决方法:我们将动态变量变成局部变量,这样垃圾回收解决内存溢出问题