
服务器
JDK 21 相较于 JDK 17 确实是一次巨大的进步。举个实际的例子来说明这一点。我有一台云
服务器,配置是 4 核 8G,平时只运行一个
wordPress 和
MySQL 8.0,负载非常低。最近我用 Kotlin 写了一个程序,目的是通过 OpenCV 比较图片的相似性。这些图片的数量大约有 15000 张。程序启动后,首先会使用 OpenCV 计算所有图片的描述符(descriptors),并将它们加载到内存中。这 15000 张图片的描述符大概需要占用 2G 的内存。接下来,我会启动 30 个线程,每个线程负责选取一张图片,并与其他 14999 张图片逐一比较,计算相似度值,最后将结果保存到
MySQL 数据库中。为了测试程序的效果,我先在自己的
电脑上运行。我的
电脑搭载了 12 代 i7 处理器和 32G 内存,但当程序运行起来后,
电脑变得非常卡顿。于是,我决定将程序部署到云
服务器上运行。当时我使用
阿里云的云效工具进行编译和部署,但由于云效不支持 JDK 21 编译,所以我只能在云
服务器上安装 JDK 17。然而,当程序启动后,云
服务器直接被拖垮了,甚至无法远程连接到
服务器。估计系统启动了某种保护机制,不久后程序就被强制杀掉了,我才得以重新登录。后来,我尝试将线程数从 30 减少到单线程,这样程序可以运行约 10 分钟左右。通过执行
free 命令,我发现可用内存逐渐下降,直到降到一定阈值时,系统再次杀掉了程序。这时我开始思考:为什么同样的程序在我的
电脑上运行时,虽然性能有所下降,但不至于完全崩溃?即使我最初设置的是 300 个线程,也只是导致键盘偶尔卡住;而当我调整为 30 个线程时,基本不会影响日常浏览网页的操作。最终,我意识到问题可能出在 JDK 版本上。我的本地
电脑使用的是 JDK 21,而云
服务器上还是 JDK 17。因此,我将云
服务器的 JDK 升级到了 21。升级后,程序终于能够稳定运行了。现在我只需要启动 2 个线程即可,此时内存占用约为 6G,4 个 CPU 核心的利用率都维持在 98% 左右。每小时可以处理 2 张图片。可以看到,程序本身没有任何改动,仅仅是更换了 JDK 版本,性能表现就发生了显著的变化。这足以证明 JDK 21 在资源管理和性能优化方面有着明显的优势。