Possible OutOfMemory when using computeIfAbsent

Rule Description: Possible out of memory when using computeIfAbsent

The computeIfAbsent documentation mentions: the mapping function given as a second argument will provide the given key to the function, in this case it will then call the HashMap or ArrayList constructor accepting an integer. This constructor allocates a HashMap or ArrayList with a given capacity. Since the key might be a large value an unnecessary large initial capacity will be allocated which can lead to an OOM.

Non compliant code:

Map<Integer, Map<X, Y>> map = ...;
Map<Integer, List<Z>> map2 = ...;
for (Integer i: values) {
    Map<X, Y> subMap = map.computeIfAbsent(i, HashMap::new);
    List<Z> subList = map2.computeIfAbsent(i, ArrayList::new);
}

Compliant code:

Map<Integer, Map<X, Y>> map = ...;
Map<Integer, List<Z>> map2 = ...;
for (Integer i: values) {
    Map<X, Y> subMap = map.computeIfAbsent(i, k -> new HashMap<>());
    List<Z> subList = map2.computeIfAbsent(i, k -> new ArrayList<>());
}

Exceptions: only applies if the map key is of type Integer.
Type: bug

Hello @Philippe_Cade

This rule RSPEC-5329: Collection constructors should not be used as java.util.function.Function seems to already report an issue for this code.

Does it make sense?

Best,
Quentin

1 Like

Hello Quentin,

Yes, this is totally it. Somehow I was not able to find it when I searched for it, sorry about that.

Thanks for looking into this.

Philippe

2 Likes

This topic was automatically closed 7 days after the last reply. New replies are no longer allowed.