[ Java ] 变量声明在循环体内还是循环体外?

2019-12-30 15:17:34 +08:00
 zhaoritian19

这是一个已经被讨论了很久的问题了,能查到的答案各种都有,请问各位大佬们有什么高见?

小白我现在项目中遇到了类似的问题,循环遍历一个对象集合,然后取其中的某些属性放入另一个对象集合中,目前是在循环的过程中 new 了新的对象,然后放入新的 list 中。在联调的时还在循环的时候日志打印了新的实体对象,但是却内存溢出项目挂掉了。   
很费解,list 的大小也就 2000 多个对象,有那么费内存吗?为什么会内存溢出?是不是将变量的声明放在循环外会好一些?希望大佬们能帮忙答疑,谢谢
4408 次点击
所在节点    Java
15 条回复
Esioner
2019-12-30 15:35:51 +08:00
list 存的是对象的引用把,如果你把变量声明放到外面会导致数据异常的问题把
Arsenal16
2019-12-30 15:39:58 +08:00
list.stream().filter(你的过滤条件).map(你要映射的属性).collect(Collectors.toList());
Java8 的话直接用这个吧。
你那个又没代码,菜鸡如我,没法排查。
Arsenal16
2019-12-30 15:47:03 +08:00
你这个应该放在循环体内创建对象,然后添加到 list
cruii
2019-12-30 17:24:46 +08:00
这样问问题就跟不贴图说自己电脑蓝屏了怎么解决一样
matepi
2019-12-30 17:36:32 +08:00
不会,循环体内变量实际会被优化提前到循环起始前
和内存占用真正有关的是 new 动作
要看你其他代码,包括 new 动作里面进一步的 new
zhaoritian19
2019-12-30 17:59:53 +08:00
@matepi 没有在 new 的实体对象里面进一步 new 别的对象,我也感觉单单是循环里面 new 实体对象不会导致内存溢出,而且才 1000 多个,GC 应该能处理的了。
zhaoritian19
2019-12-30 18:01:14 +08:00
@Arsenal16 老项目了用的 java7,没有升级到 java8。 如果是 8 就不会用循环来做了
chendy
2019-12-30 18:14:17 +08:00
内存溢出的话,用 -XX:+HeapDumpOnOutOfMemoryError 导出 dump,然后 mat 分析 dump 看是什么东西占用了太多内存
2000 不多,但是也不知道每个对象多大,所以不好说…
passerbytiny
2019-12-30 18:16:27 +08:00
变量声明应该放到循环体外(然并卵,减少的内存占用相对来说可以忽略),但给 list 的对象一定是在循环体内 new 出来的。

list 上万都没问题,你这个能溢出应该是其他原因,需要根据 JVM 异常日志去定位。
palmers
2019-12-30 19:39:03 +08:00
得看看是堆内存还是栈内存 还有 同意 8#的同学把对应日志 dump 出来看看占用在哪里 问题原因应该就出来了
choice4
2019-12-31 01:04:00 +08:00
2000 个就溢出,,java 再费内存也没这么个费法啊
nnnToTnnn
2019-12-31 08:47:40 +08:00
Java 无论是在循环体内还是循环体外,由于 java 特定的 gc 机制,就算你在循环体内声明了变量,也不可能内存溢出!!!

除非有些引用没有被 gc,例如很简单的 ThreadLocal 中使用了 map,这种内存溢出的操作。
LaughingCat
2019-12-31 09:46:47 +08:00
我以前也遇到过这种循环 new 溢出的问题,当在循环次数达到一定数量时,new 操作会在占用大量的内存空间,解决方式是在外面 new 一个对象,这个对象有处理数据的构造函数,然后在循环里面对该对象进行构造函数赋值就能达到你要的循环 new 的效果。
rizon
2019-12-31 15:05:36 +08:00
这事我也很纠结,正常来说,从代码的可读性来说,放到循环体内生命更合适,但是很多人又说处于性能考虑应该放到循环体外。
我一般考虑可读性。 但是也是希望能得到一个更明确点的答案。
至于内存泄漏问题,在 java 里是不存在的,搞 C 的才有这个问题。
mightofcode
2020-01-06 11:55:22 +08:00
贴代码比较好,看描述看不明白

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/633576

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX