Java流遍历数组时是否会占用大量额外内存?
先明确你的问题场景:你有一段代码:
Arrays.stream(queries).limit(queries.length - 1).mapToInt(i -> i).sum();
其中queries是包含100万个整数的数组(约占4MB内存),想知道执行这段代码时,Java流会不会产生可观的额外内存开销,还是仅依赖原数组的内存就能完成计算。
好问题!咱们来一步步拆解这段代码的内存情况:
Arrays.stream(queries)的本质:这个方法返回的是一个基于原数组的IntStream(因为输入是int数组),它本质上是一个数组的"包装器",不会复制原数组的任何元素。这个流对象本身只占用极少量内存——无非是几个对象引用、遍历位置计数器这类小变量,完全不会额外分配4MB的内存空间。limit(queries.length - 1)的内存影响:这是一个惰性的中间操作,它不会提前处理或缓存元素,只是给流的遍历加上了一个终止条件:当遍历到第queries.length - 1个元素时就停止。这个操作只会维护一个简单的计数状态,内存开销可以忽略不计。mapToInt(i -> i)的多余性与内存:其实这里的转换是多余的——因为Arrays.stream(int[])本来就返回IntStream,不需要再转一次。不过就算保留这个操作,它也是一个无状态的中间操作,遍历元素时只是做个"透传",不会缓存任何元素,几乎不占用额外内存。sum()终端操作的执行:这个操作会触发流的遍历,它会逐个读取原数组中的元素(从第一个到倒数第二个),边遍历边累加求和。整个过程中不会把元素批量加载到额外的内存结构里,完全依赖原数组的内存完成计算。
总结
这段代码除了原数组本身占用的4MB内存,流相关的对象只会占用非常少的额外内存(大概几十到几百字节的级别),完全不需要重新分配整个数组,也不会产生可观的额外内存开销。
内容的提问来源于stack exchange,提问作者user7858768

