为何这段Java代码抛出OutOfMemoryError?方法引用与Lambda的差异
堆内存溢出原因分析:computeIfAbsent方法引用的误用
这段代码在JDK 17、18、19中使用line2的方法引用写法会触发OutOfMemoryError: Java heap space,但换成line1的Lambda写法就能正常运行,核心原因是方法引用错误匹配了HashSet的构造器:
HashMap.computeIfAbsent的第二个参数是Function<? super K, ? extends V>,需要接收当前的键(此处为Integer类型的x),并返回对应的值类型(HashSet)。 - line1的Lambda写法
_x -> new HashSet<>()逻辑正确:无论传入的键是什么,都会调用HashSet的无参构造器创建空集合,初始容量为默认的16,不会有内存问题。 - line2的
HashSet::new方法引用,会自动匹配到HashSet中接收int参数的构造器(public HashSet(int initialCapacity))——因为computeIfAbsent会将当前的键x(如305589003、305589004这类超大整数)作为参数传入该构造器。 - 当传入的初始容量达到3亿级别时,HashSet底层依赖的HashMap会尝试分配对应大小的数组,瞬间耗尽堆内存,进而触发内存溢出异常,这也是调试时发现
HashMap.resize()中newCap值异常巨大的原因。
内容的提问来源于stack exchange,提问作者djy
相关产品推荐
相关产品推荐

