看到一个很有创意的应用启动加速文章:
piotrminkowski.com/2023/08/22/resize-cpu-limit-to-speed-up-java-startup-on-kubernetes/
核心思路就是在启动时调大 CPU 核数,启动完成后再调回原来的 CPU 核数

看评论,这种方式对于 Java 应用,可能会对 GC 有影响。不知道有没有人在生产环境使用过这种启动加速方式,会不会有坑。

你们 Java 应用一般都是长时间运行的启动阶段占比极低研究这个没啥意义

哈哈哈 java 的启动时间真的一言难尽

依稀记得有个帖子优化 java 应用启动时间,被好多人喷

研究的过程还是很有意思的,接触到了很多新的概念

#3 这个帖子好像也是我发的😂

我一只觉得启动慢都是框架的 class 层数太多导致的其实也没干多少实事吧但是因为是层叠结构,加 cpu 核能起到什么效果吗?

我觉得这个是需要看具体的 Java 应用,如果某应用启动的时候并发操作多,可被多核优化,那么效果就明显,否则效果就不太好。他的对比验证选了 0.5 核做对比就比较鸡贼,2 核启动花了 10-15s ,0.5 核启动花了 40s ,0.5 核的情况下单核心的时间片都被分走一半了,启动效果打折是很明显的。

我好像听说有的手机厂商对微信有优化,点开微信就在 CPU 上做手脚,让系统“看起来”更流畅

#6 是的,特别是 spring 框架下,启动过程是单线程的,这样添加 CPU 核数可能作用不大,但是可以通过一些手段,将耗时的 Bean 的初始化方法异步化,这样添加 CPU 核数可能就有用了

初始化方法异步化,是不是得修改源代码啊?似乎并不是直接加核就能生效的吧?

思路很有意思但是感觉意义不大,因为启动速度慢一般不是因为资源不够而是资源利用率不高启动慢的一般是要加载的 class 多,要扫描的包多,但是印象里这玩意是单线程的,加核心数没用启动特别慢的一般是启动过程中要查数据库之类的,加核心数也没用所以,这个操作对于启动过程中会用多线程的应用有用,另外可能会影响 gc 的一些参数(收集器线程数啥的)

#10 这个我之前实现过,就是需要引入个 jar 包,通过动态代理的方式,将初始化方法丢到线程池中,最后等待启动完成

厉害了

是的,刚看到这种方法的时候,觉得很有创意

有一个点就是,Java 应用启动后一般会有一个预热过程,这个过程添加核心数会很有用

哈哈哈,我还看到过反向操作的,不知道真假,就是点开其他 app 的时候,自己的 app 就疯狂占用 CPU ,让别人的 app 操作卡顿

对于 spring 这种主线程启动的服务来说,没啥用

确实有,而且已经标准化了 github.com/Tencent/Hardcoder

Android 上面超级应用微信、相机等加速启动都是通过这种方式来的

Java 搞个常驻, 类似 Zygote 或者 Chrome, 就不用担心启动时间的问题了

这个看起来还行,或者给个参数 kubelet 调用高性能节点快速启动应用, 然后滚动到正常节点?

java 要搞常驻的。隔壁 python 和 node.js 的容器冷启动才 0.3 秒,没法比啊。