PageSourceSearch

http://ibeetl.com/assets/index.html-CQ3XMMQn.js

js ibeetl.com collected 2026-10-03 23:19:48 UTC 10,682 bytes, 1 lines download raw bytes

1import{_ as e,c as l,b as a,o as i}from"./app-CNefOTx1.js";const d="/assets/vminit-Cd1qBu09.png",r={};function n(s,t){return i(),l("div",null,t[0]||(t[0]=[a('<h2 id="_5-12-加速应用启动" tabindex="-1"><a class="header-anchor" href="#_5-12-加速应用启动"><span>5.12 加速应用启动</span></a></h2><p>绝大多数开发人员早就被业务系统重启慢这个问题折磨过,想象你开发时候的微调代码,部署后重启需要1分钟或者数分钟才能验证,恐怕这时候你会去看看手机新闻或者和和同事聊会天,等待系统启动完毕,因此耽误开发时间和打断工作节奏。</p><p>运维大规模部署这种系统,也会延长部署时间,尤其云原生应用,频繁创建和销毁应用,希望业务系统功能尽快启动,尽快平稳提供服务。下图展示了一个应用启动的过程,从启动到能提供高并发服务,需要一系列过程</p><p><img src="'+d+'" alt=""></p><table><thead><tr><th style="text-align:left;">过程</th><th style="text-align:left;">描述</th></tr></thead><tbody><tr><td style="text-align:left;">Java命令</td><td style="text-align:left;">通过Java命令创建JVM,此时调用的是本地so或者dill文件</td></tr><tr><td style="text-align:left;">JVM初始化</td><td style="text-align:left;">申请堆空间,初始化垃圾回收器,JIT等。</td></tr><tr><td style="text-align:left;">类加载</td><td style="text-align:left;">加载Bootstrap ClassLoader,启动JDK核心类,然后启动应用程序的ClassLoader,加载应用程序的类,第三方类等</td></tr><tr><td style="text-align:left;">JIT优化</td><td style="text-align:left;">分阶段优化应用。C1编译器把字节码转化为本地机器码,后续JIT对方法调用,循环等操作计数确认重点优化方法,并使用C4实现内联等优化手段。</td></tr><tr><td style="text-align:left;">开发框架初始化</td><td style="text-align:left;">采用的开发框架,如Spring Boot,Solon等,需要一个初始化过程,比如扫描所有类确定Web服务接口</td></tr><tr><td style="text-align:left;">第三方包初始化</td><td style="text-align:left;">比如数据库连接池初始化,微服务框架通过API定义生成实现类等。</td></tr><tr><td style="text-align:left;">应用初始化</td><td style="text-align:left;">应用自己初始化的过程,比如创建一个缓存,或者Netty的服务器端口监听等</td></tr><tr><td style="text-align:left;">高并发服务</td><td style="text-align:left;">此阶段应用程序才能提高并发服务</td></tr></tbody></table><p>如何加速业务系统启动和凯苏快速高并发服务,针对上图的各个阶段,有不同的解决方案,按照优先级排列,投入较小而获得最大收益:</p><ul><li>能否避免重启,比如通过配置,规则引擎来调整经常变化的业务逻辑</li><li>是否能采用热加载技术来避免JVM重启,比如ClassLoader技术加载经常变化的业务模块,JVM底层的类替换技术(类重定义Redefine,类替换DECVM)</li><li>审查框架,是否启动过程加载过多内容,比如Spring Boot启动时候,会扫描类路径。可以限定其扫描的特定包而不需要扫描所有包。一些轻量级框架Jfinal,Solon对启动做了专门优化,有较快的启动速度</li><li>审查依赖第三方包,是否初始化较慢。比如数据库连接池,如果配置初始化连接个数较大,会影响启动。开发环境可以设置一个较小的数</li><li>审查应用,是否有加载较慢的对象,比如应用中,某个缓存类需要加载所有数据。建议改成懒加载,或者只加载热数据。</li><li>优化JIT,比如设置<code>-XX:TieredStopAtLevel=1</code> 限制JIT 消耗CPU做极致优化,使得系统能较快启动和提供服务。此比较适合需要经常重启应用,比如特定的微服务或者Serverless</li><li>优化JVM,比如开启类共享。避免加载Class耗时。JDK17后使用<code>‑XX:SharedArchiveFile</code></li><li>观测启动后到流量稳定这段时间JVM性能,比如通过VisualVM来获得CPU采样,内存采用,找到不必要的耗时以及并发瓶颈(生产系统系统功启动后,可能有较大流量的访问)。 比如Netty启动后Netty申请较大内存块作为缓存.</li><li>采用AOT技术,预先编译Java程序为二进制,避免了JVM的类加载,JIT的优化编译过程。但是采用AOT技术,其不支持动态类加载和字节码等,可能要调整应用配置和第三方包(有些第三方包不支持AOT),风险较大。除非你的应用刚开始就是按照AOT来规划的。</li></ul><p>有些文章里提到设置JMV较小的堆内存能帮助JMV启动,这是错的,因为JVM启动时候向操作系统申请堆内存,操作系统分配的是虚拟内存,只有在使用的时候才会分配物理内存。</p><p>值得注意的是,有俩个需要关注的JVM技术,虽然还暂时未能合并到OpeneJDK(某些商业JDK已经支持),但业界已经验证其能极大提高系统启动和运行速度,他几乎一步到位使得应用能立即提高高并发访问。</p><ul><li>采用支持Leyden ,将JIT优化后的代码缓存为存档文件,当JVM再次启动时候,JIT可以直接加载使用。</li><li>采用 CRaC ,类似镜像快照技术,支持保存JVM的快照,下次重启可以直接从检查点恢复。具备最快的启动和运行速度。CRaC涉及到快照保存和恢复,需要应用程序写特定的回掉函数,比如网络服务程序,在使用CRac恢复后,需要重启监听端口。</li></ul><p>需要说明的是,OpenJDK针对JVM启动慢,预热时间长的问题,自从JDK5以来就有各种解决办法,目前看来Leyden 和 CRaC 技术是最适合的。如下是互联上的一组实验数据,一个基于Spring Boot的应用</p><table><thead><tr><th style="text-align:left;">场景</th><th style="text-align:left;">启动延迟</th><th style="text-align:left;">内存占用</th></tr></thead><tbody><tr><td style="text-align:left;">传统单体应用</td><td style="text-align:left;">3000ms+</td><td style="text-align:left;">1.5GB+</td></tr><tr><td style="text-align:left;">CRaC基础微服务</td><td style="text-align:left;">300ms</td><td style="text-align:left;">300MB</td></tr><tr><td style="text-align:left;">Leyden+CRaC应用</td><td style="text-align:left;">30ms</td><td style="text-align:left;">50MB</td></tr></tbody></table><blockquote><p>数据来自 https://blog.csdn.net/m0_65465065/article/details/149158057</p></blockquote><p>本节的建议包含较多基础知识,如下是在本书提到</p><table><thead><tr><th style="text-align:left;">术语</th><th style="text-align:left;">引用章节</th></tr></thead><tbody><tr><td style="text-align:left;">配置</td><td style="text-align:left;">8 高可用 可配置系统</td></tr><tr><td style="text-align:left;">脚本引擎</td><td style="text-align:left;">
18 高可用 使用脚本引擎&amp;规则引擎</td></tr><tr><td style="text-align:left;">热加载</td><td style="text-align:left;">8 高可用章节 热部署</td></tr><tr><td style="text-align:left;">热数据</td><td style="text-align:left;">5 数据冷热处理</td></tr><tr><td style="text-align:left;">TieredStopAtLevel</td><td style="text-align:left;">6.3 JIT</td></tr><tr><td style="text-align:left;">VisualVM</td><td style="text-align:left;">4.4 观察单机系统功运行</td></tr><tr><td style="text-align:left;">AOT</td><td style="text-align:left;">5.19 AOT</td></tr><tr><td style="text-align:left;">JIT</td><td style="text-align:left;">6.3 JIT</td></tr><tr><td style="text-align:left;">对象池</td><td style="text-align:left;">5.2 对象池</td></tr></tbody></table><p>都是</p>',16)]))}const p=e(r,[["render",n],["__file","index.html.vue"]]),y=JSON.parse('{"path":"/article/performance/policy_codestart/","title":"性能优化-加速应用启动","lang":"en-US","frontmatter":{"title":"性能优化-加速应用启动","tags":["性能","新书"],"createTime":"2026/08/21 13:06:15","permalink":"/article/performance/policy_codestart/","description":"5.12 加速应用启动 绝大多数开发人员早就被业务系统重启慢这个问题折磨过,想象你开发时候的微调代码,部署后重启需要1分钟或者数分钟才能验证,恐怕这时候你会去看看手机新闻或者和和同事聊会天,等待系统启动完毕,因此耽误开发时间和打断工作节奏。 运维大规模部署这种系统,也会延长部署时间,尤其云原生应用,频繁创建和销毁应用,希望业务系统功能尽快启动,尽快平稳...","head":[["meta",{"property":"og:url","content":"http://ibeetl.com/article/performance/policy_codestart/"}],["meta",{"property":"og:site_name","content":"闲大赋"}],["meta",{"property":"og:title","content":"性能优化-加速应用启动"}],["meta",{"property":"og:description","content":"5.12 加速应用启动 绝大多数开发人员早就被业务系统重启慢这个问题折磨过,想象你开发时候的微调代码,部署后重启需要1分钟或者数分钟才能验证,恐怕这时候你会去看看手机新闻或者和和同事聊会天,等待系统启动完毕,因此耽误开发时间和打断工作节奏。 运维大规模部署这种系统,也会延长部署时间,尤其云原生应用,频繁创建和销毁应用,希望业务系统功能尽快启动,尽快平稳..."}],["meta",{"property":"og:type","content":"article"}],["meta",{"property":"og:locale","content":"en-US"}],["meta",{"property":"og:updated_time","content":"2026-08-24T05:21:51.000Z"}],["meta",{"property":"article:tag","content":"性能"}],["meta",{"property":"article:tag","content":"新书"}],["meta",{"property":"article:modified_time","content":"2026-08-24T05:21:51.000Z"}],["script",{"type":"application/ld+json"},"{\\"@context\\":\\"https://schema.org\\",\\"@type\\":\\"Article\\",\\"headline\\":\\"性能优化-加速应用启动\\",\\"image\\":[\\"\\"],\\"dateModified\\":\\"2026-08-24T05:21:51.000Z\\",\\"author\\":[]}"]]},"headers":[],"readingTime":{"minutes":5.24,"words":1571},"git":{"updatedTime":1787548911000,"contributors":[{"name":"lijiazhi","username":"lijiazhi","email":"[email protected]","commits":2,"avatar":"https://gravatar.com/avatar/1b5114831459724ad4acc394423b4b48ecfa4a7e0659fbe07a0ce5181a1050a7?d=retro"}]},"autoDesc":true,"filePathRelative":"article/性能/coldstart.md","categoryList":[{"id":"92a2b5","sort":10000,"name":"article"},{"id":"afdb50","sort":10004,"name":"性能"}]}');export{p as comp,y as data};

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.