Java lambda 表达式和内存分配

标签 java

假设我们有这三种方法。它们都做同样的事情,但它们在内存分配和效率方面有何不同?方法一会在每次调用期间创建 Function 的实例,但方法二会做同样的事情吗?应该始终使用第三个版本还是其中一个版本是安全的并且 JIT 编译器将负责内存优化?

class Test {
    Map<String, Set<String>> mapOfSets = new HashMap<>();
    static final Function<String, Set<String>> FUNCTION = s -> new HashSet<>();

    void method1(String key, String value) {
        Function<String, Set<String>> func = s -> new HashSet<>();
        mapOfSets.computeIfAbsent(key, func).add(value);
    }

    void method2(String key, String value) {
        mapOfSets.computeIfAbsent(key, s -> new HashSet<>()).add(value);
    }

    void method3(String key, String value) {
        mapOfSets.computeIfAbsent(key, FUNCTION).add(value);
    }
}

最佳答案

如评论所述,这可能会根据您使用的 Java 实现而改变。

对于热点 jvm(普通/默认 java 实现),您可以预期所有 3 个选项在性能方面都是相同的。一开始您可能认为 3 可能更好,因为 1 和 2 可能需要在每次调用时创建一个新的 Function 对象。但是,您假设每次都需要为 method1(和 2)创建一个新对象是错误的,因为非捕获 lambda 将缓存在调用站点,因此每次调用都会重复使用同一个实例,就像 method3 一样你不会看到任何区别。

this answer是并且对该主题的出色概述更详细

因此,在这种情况下,您可以放心地使用这三种中的任何一种,因此请使用最适合您情况的一种。

关于Java lambda 表达式和内存分配,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53892875/

相关文章:

Java JVM 根据操作系统保持内存分配

java - 使用预先存在的 AES key 在 Java 中解密文件

java - jar 文件可以在运行时重命名或删除自身吗?

Javax Jersey 客户端处理异常

java - 将大矩阵表示为一维数组比二维数组更有效吗?

java - Java 中的代理 - 客户端不显示响应?

java - SealedObject 与 Stream Cypher,优缺点

java - JDI/JPDA 事件过滤

java - 评级 field (Foursquare)

java - Snakeyaml 似乎不必要地将简单值包装在列表中