17 | 别以为“自动挡”就不可能出现OOM
该思维导图由 AI 生成,仅供参考
- 深入了解
- 翻译
- 解释
- 总结
文章总结:本文通过案例展示了Java中WeakHashMap可能导致OOM的问题,并提供了解决方案和替代方案。作者以用户数据缓存为例,说明了使用WeakHashMap时可能出现的内存泄漏问题,指出WeakHashMap的Value持有Key中对象的强引用导致Key无法回收,建议使用WeakReference包装Value来解决。另外,文章还介绍了Spring提供的ConcurrentReferenceHashMap,该类不仅性能更好,还可以确保线程安全。此外,文章还分享了Tomcat参数配置不合理导致OOM的案例,强调了参数配置需根据实际需求来修改,避免占用不必要的资源。总结指出,读者在使用WeakHashMap时需注意内存泄漏问题,同时提供了解决方案和替代方案。文章通过具体案例和源码分析,深入浅出地解释了WeakHashMap可能出现的OOM问题,对读者编写业务代码时避免出现OOM问题具有一定的借鉴意义。
《Java 业务开发常见错误 100 例》,新⼈⾸单¥59
全部留言(15)
- 最新
- 精选
- 一个汉子~针对第二点,可以先compile,然后在内存中保存,脚本内容的hash作为key,compile结果作为value,用ConcurrentReferenceHashMap保存 同样的风险还出现在表达式框架aviator中
作者回复: 👍🏻
2020-04-18327 - Darren试着回到下问题: 第一个: 肯定是软引用,因为弱引用是只要GC执行,扫描到就被回收,缓存的作用是为了提高速度,要有一定的存在周期;如果是弱引用,每次GC执行,缓存被回收,缓存命中率超低,完全达不到缓存的作用,而又要维护缓存和DB的数据一致性问题,得不偿失。 第二个: 第一种不完美的方案:GroovyShell不要设置成全局的,每次运行时,都创建一个GroovyShell,然后限制元数据区大小,当元数据回收时,GroovyShell和该GroovyShell加载的类一起被回收; 第二种方法:GroovyShell设置为全局的,然后使用缓存,每次都是先从缓存中获取,获取不到了,在加载,然后更新缓存。
作者回复: 源码里我也有一个例子,思路是不要每次都evaluate脚本而是把脚本转变为一个方法parse后缓存起来这个Script,以后直接invokeMethod来使用
2020-04-20312 - 汝林外史1. 对于老师说的autoComplete的场景是不是Trie树更适合一些? 2. 这个WeakReference可能导致内存溢出的典型就是ThreadLocal,虽然ThreadLocalMap的entry的key是weakReference,但是value是强引用,当用线程池的时候,就会内存溢出,还是要自己remove才行。 3. 对于问题1,应该是用软引用更好一些,用弱引用总是被gc回收就失去了缓存的意义。对于问题2不是很了解。
作者回复: 1. 👍 是的,这种场景字典树更合适,不过我这边都是拿着实际的案例整理成文的,主要是希望告知大家我们认为的一份数据在程序中不一定是一份这个误区
2020-04-2012 - 👽应该用哪种引用,首先考虑的肯定是四大引用的区别。 1.强引用:最常见的一种,只要该引用存在,就不会被GC。 2.软引用:内存空间不足时,进行回收。 3.弱引用:当JVM进行GC时,则进行回收,无论内存是否充足。 4.虚引用:这个不提了,因为我也完全不懂。 软引用和弱引用,这两个,让我选,肯定是选软引用。因为弱引用,被回收的频率更高。缓存,如果经常被回收的话,就达不到最大利用率。 但是这里又要说点额外的,单说缓存设计,还要涉及其他的因素。包括缓存大小,缓存的过期时间等。让我来说的话,我可能会考虑使用现有的缓存实现,或者是redis。自己实现一套缓存,成本略高。
作者回复: 不错
2020-04-1829 - 一个汉子~之前还遇到一个,一个导出功能,拥有管理员权限的人几乎没有限制,造成了全表查,再加上框架禁止join,所以又把外键拉出来做了一次in查询,也是全表扫,大量的Bo对象和超长sql,直接把系统oom了
作者回复: 很常见的问题,还有包括参数未传导致mybatis条件没有拼接上去,导致全表查询的oom
2020-04-1838 - 不能忍的地精我遇到一个OOM,是这样的 1. 首先有一个线程池,线程数量是20个,但是线程队列容器的数量是Integer的最大值,所以拒绝策略几乎无效,大概没过3秒往线程池提交3个任务 2. 任务里面有一个Restemplate,没有设置超时时间,超时时间为-1,并且里面维护的连接池是5个,小于线程池数量 3. 出现5个连接都超时,任务卡住了,但是还是不断的往任务队列里面添加任务,最终导致OOM
作者回复: 😥
2020-04-247 - ddosyang老师想问一下,在WeakHashMap的那个例子里,可不可以直接用String name当作Key,而不是用User做Key。这样是不是也可以解决问题?
作者回复: 是,不过这就改了设计了
2020-04-202 - Carisy老师请教一个问题,在使用CompletableFuture的时候出现了很奇怪的场景,就是buffers飙升出现oom,应用程序使用内存并不多,处理逻辑也相对简单就是调用接口通过http上传下载文件
作者回复: buffers是指什么buffer?这个和CompletableFuture没有关系,上传下载都会用到缓冲区,如果并发大的话可能是会OOM
2020-06-051 - 旅途有点没懂 java.lang.IllegalArgumentException: Request header is too large 的意思不就是request header过大了么 为什么开发人员还设置的那么大?
作者回复: 这个异常原因是请求头数据过大超过了限制 不是指tomcat请求头参数配置过大
2020-04-2821 - pedro问题一,弱引用是在内存不足时被 gc 掉,而软引用是只要 gc 就回收掉,自然就不能用来做缓存,否则动不动就缓存失效,数据库怕是要被玩坏哦,因为适合做缓存的是弱引用。 问题二,没用过 groovy,希望看到别人的解答。😄
作者回复: 不太对,可以再查一些资料或做一些实验看下软和弱的区别
2020-04-1831