在我们开始讨论策略之前,让我们先了解启动时间和内存占用在 Java 应用程序的上下文中意味着什么。
启动时间是指Java应用程序启动后到准备好处理请求所需的时间。对于快速部署和可用性至关重要的应用程序来说,最大限度地缩短启动时间至关重要。
Java 应用程序的内存占用是其运行时消耗的内存量。较大的内存占用可能会导致更高的成本和增加的延迟,尤其是在云环境中。
在这里,我们将探索各种方法来减少 Java 应用程序的启动时间。
类数据共享(CDS)是一种允许 JVM 在多个 Java 进程之间共享公共类元数据的技术,从而减少加载类所需的时间。
示例:
java -Xshare:dump -XX:+UseAppCDS -XX:SharedClassListFile=classlist -XX:SharedArchiveFile=app-cds.jsa -cp myapp.jar
此命令生成一个共享存档,可用于通过使用预加载的类更快地启动应用程序。
启用 CDS 可以减少大约 15% 的启动时间,具体取决于应用程序的复杂性。
GraalVM 允许您将 Java 代码编译为本机二进制文件,通过避免 JVM 预热来显着减少启动时间。
GraalVM 是一种先进的多语言虚拟机,不仅支持多种语言,还提供用于优化 Java 应用程序的强大功能。 GraalVM 的突出功能之一是将 Java 应用程序编译为本机二进制文件的能力。此过程称为提前 (AOT) 编译,它带来了显着的性能优势,特别是在减少启动时间方面。
当您使用 GraalVM 的 Native Image 工具编译 Java 应用程序时,整个应用程序及其依赖项和 JVM 的必要部分将被编译为单个本机可执行文件。该可执行文件可以直接在操作系统上运行,无需 Java 虚拟机 (JVM) 来解释字节码。
示例:
java -Xshare:dump -XX:+UseAppCDS -XX:SharedClassListFile=classlist -XX:SharedArchiveFile=app-cds.jsa -cp myapp.jar
此命令将您的应用程序转换为本机可执行文件,从而几乎瞬时启动。
使用 GraalVM Native Image 可以减少高达 90% 的启动时间,尽管这需要彻底的测试,因为它可能不支持所有 Java 功能。
AOT 编译涉及在应用程序运行之前将 Java 字节码提前翻译为本机机器代码。此过程生成一个可执行二进制文件,其中包括已编译的机器代码和任何必要的运行时组件。目标是消除或最小化应用程序启动和执行期间对 JIT 编译的需求。
在 AOT 编译过程中,Java 编译器或 GraalVM 的 Native Image 等专用工具会从 Java 源代码生成本机可执行文件。然后,使用该本机代码直接执行应用程序,无需 JVM 即时执行 JIT 编译。
示例:
native-image -jar myapp.jar
该命令预编译特定方法,减少 JIT 编译的时间。
AOT 可以减少大约 10% 的启动时间,特别是对于具有复杂初始化序列的应用程序。
减少类路径中的类和库的数量也有助于缩短启动时间。
示例 :使用 jlink 等工具创建自定义 JRE:
java -XX:+UnlockExperimentalVMOptions -XX:AOTLibrary=./myapp.so -cp myapp.jar
这个自定义 JRE 仅包含您的应用程序所需的模块,从而减少了开销。
此优化可以通过消除加载不必要的类来减少 5-10% 的启动时间。
减少内存占用对于扩展应用程序至关重要,尤其是在资源根据使用情况计费的云环境中。
G1 垃圾收集器旨在最大限度地减少暂停时间,并可以通过压缩活动对象来减少内存使用量。
示例
jlink --module-path $JAVA_HOME/jmods --add-modules java.base,java.sql --output custom-jre
此命令将 JVM 配置为使用具有优化堆设置的 G1 GC。
G1 GC 在具有大量实时数据的应用程序中可以减少高达 30% 的内存占用。
调整 JVM 内存设置(例如堆大小、堆栈大小和元空间)可以显着减少内存占用。
示例:
java -Xshare:dump -XX:+UseAppCDS -XX:SharedClassListFile=classlist -XX:SharedArchiveFile=app-cds.jsa -cp myapp.jar
此命令微调堆和元空间设置以减少内存消耗。
仔细的内存调整可以使内存使用量减少 20-30%。
JVM 可以检测重复的字符串并在内存中仅存储一份副本,从而在应用程序使用许多相同的字符串时节省空间。
示例:
native-image -jar myapp.jar
此命令启用字符串去重,在存在许多重复字符串时减少内存使用。
字符串去重可以减少高达 10% 的内存使用量,特别是在文本较多的应用程序中。
过多的对象创建会增加内存使用量。使用对象池或不可变对象来最大限度地减少不必要的分配。
示例:
java -XX:+UnlockExperimentalVMOptions -XX:AOTLibrary=./myapp.so -cp myapp.jar
这种单例模式减少了应用程序生命周期中创建的对象数量。
减少对象创建可以减少 10-20% 的内存使用量,具体取决于应用程序的结构。
优化 Java 应用程序的启动时间和内存占用可以显着提高性能并节省成本。通过实施所讨论的策略(例如启用 CDS、使用 GraalVM、AOT 编译和内存调整),您可以实现所需的启动时间减少 60% 和内存使用量减少 50%。这些优化在云平台等资源受限的环境中特别有效。
请记住,每个应用程序都是独一无二的,因此必须在您的特定环境中测试这些策略,以确保它们提供预期结果。
如果您对这些技术有任何疑问或需要进一步说明,请随时在下面发表评论!
阅读更多帖子:将 Java 应用程序的启动时间和内存占用减少多达 60% 的策略
以上是将 Java 应用程序的启动时间和内存占用量减少最多的策略的详细内容。更多信息请关注PHP中文网其他相关文章!