通过静态分析、映像初始化和堆快照提高性能
一分耕耘,一分收获!既然都打开这篇《通过静态分析、映像初始化和堆快照提高性能》,就坚持看下去,学下去吧!本文主要会给大家讲到等等知识点,如果大家对本文有好的建议或者看到有不足之处,非常欢迎大家积极提出!在后续文章我会继续更新文章相关的内容,希望对大家都有所帮助!
从整体结构到分布式系统世界,应用程序开发已经走过了漫长的道路。云计算和微服务架构的大规模采用极大地改变了服务器应用程序的创建和部署方式。我们现在拥有独立、单独部署的可立即投入使用的服务,而不是庞大的应用程序服务器
在需要时。
然而,区块上可能影响这种平稳运行的新玩家可能是“冷启动”。当第一个请求在新生成的工作线程上处理时,冷启动就会启动。这种情况需要在处理实际请求之前进行语言运行时初始化和服务配置初始化。与冷启动相关的不可预测性和执行速度较慢可能会违反云服务的服务级别协议。那么,如何应对这种日益增长的担忧呢?
本机映像:优化启动时间和内存占用
为了解决冷启动的低效率问题,我们开发了一种新颖的方法,涉及点分析、构建时的应用程序初始化、堆快照和提前 (aot) 编译。此方法在封闭世界假设下运行,要求所有 java 类在构建时都已预先确定并可访问。在此阶段,全面的点分析确定所有可访问的程序元素(类、方法、字段),以确保仅编译必要的 java 方法。
应用程序的初始化代码可以在构建过程中执行,而不是在运行时执行。这允许预先分配 java 对象并构建复杂的数据结构,然后在运行时通过“映像堆”提供这些数据结构。该映像堆集成在可执行文件中,在应用程序启动时提供立即可用性。
持续迭代执行点分析和快照,直到达到稳定状态(定点),从而优化启动时间和资源消耗。
详细工作流程
我们系统的输入是 java 字节码,它可能源自 java、scala 或 kotlin 等语言。该过程统一处理应用程序、其库、jdk 和 vm 组件,以生成特定于操作系统和体系结构的本机可执行文件 - 称为“本机映像”。构建过程包括迭代点分析和堆快照,直到达到固定点,从而允许应用程序通过注册的回调主动参与。这些步骤统称为本机映像构建过程(图 1)
图 1 – 本机映像构建过程(来源:redhat.com)
点分析
我们采用点分析来确定运行时类、方法和字段的可达性。点到分析从所有入口点(例如应用程序的主要方法)开始,迭代遍历所有可传递可达的方法,直到到达固定点(图 2)。
图 2 – 分析点
我们的指向分析利用编译器的前端将 java 字节码解析为编译器的高级中间表示(ir)。随后,ir 被转换为类型流图。在此图中,节点表示对对象类型进行操作的指令,而边表示节点之间的定向使用边,从定义指向使用。每个节点维护一个类型状态,由可以到达该节点的类型列表和空值信息组成。类型状态通过使用边传播;如果节点的类型状态发生变化,则此更改将传播到所有用途。重要的是,类型状态只能扩展;新类型可以添加到类型状态中,但现有类型永远不会被删除。该机制确保
分析最终收敛到一个固定点,导致终止。
运行初始化代码
指向分析指导初始化代码在到达本地固定点时的执行。该代码起源于两个不同的来源:类初始值设定项和在构建时通过功能接口批量执行的自定义代码:
类初始值设定项: 每个 java 类都可以有一个由
方法指示的类初始值设定项,该方法初始化静态字段。开发人员可以选择在构建时和运行时初始化哪些类。 显式回调:开发人员可以通过我们系统提供的钩子实现自定义代码,在分析阶段之前、期间或之后执行。
这里提供了用于与我们的系统集成的 api。
被动api(查询当前分析状态)
boolean isreachable(class<?> clazz); boolean isreachable(field field); boolean isreachable(executable method);
更多信息,请参阅 queryreachabilityaccess
active api(注册分析状态更改的回调):
void registerreachabilityhandler(consumer<duringanalysisaccess> callback, object... elements); void registersubtypereachabilityhandler(biconsumer<duringanalysisaccess, class<?>> callback, class<?> baseclass); void registermethodoverridereachabilityhandler(biconsumer<duringanalysisaccess, executable> callback, executable basemethod);
更多信息,请参阅beforeanalysisaccess
在此阶段,应用程序可以执行自定义代码,例如对象分配和较大数据结构的初始化。重要的是,初始化代码可以访问当前的分析状态点,从而启用有关类型、方法或字段的可达性的查询。这是使用duringanalysisaccess 提供的各种isreachable() 方法来完成的。利用此信息,应用程序可以构建针对应用程序的可到达段进行优化的数据结构。
堆快照
最后,堆快照通过像静态字段一样跟随根指针构建对象图,以构建所有可访问对象的全面视图。然后该图填充本机图像的
图像堆,确保应用程序的初始状态在启动时高效加载。
为了生成可达对象的传递闭包,该算法遍历对象字段,使用反射读取它们的值。需要注意的是,映像生成器在 java 环境中运行。在此遍历期间,仅考虑由指向分析标记为“已读”的实例字段。例如,如果一个类有两个实例字段,但其中一个未标记为已读,则通过未标记字段可访问的对象将从图像堆中排除。
当遇到先前未通过指向分析识别其类的字段值时,该类将被注册为字段类型。此注册可确保在点分析的后续迭代中,新类型传播到类型流图中的所有字段读取和传递用法。
下面的代码片段概述了堆快照的核心算法:
Declare List worklist := [] Declare Set reachableObjects := [] Function BuildHeapSnapshot(PointsToState pointsToState) For Each field in pointsToState.getReachableStaticObjectFields() Call AddObjectToWorkList(field.readValue()) End For For Each method in pointsToState.getReachableMethods() For Each constant in method.embeddedConstants() Call AddObjectToWorkList(constant) End For End For While worklist.isNotEmpty Object current := Pop from worklist If current Object is an Array For Each value in current Call AddObjectToWorkList(value) Add current.getClass() to pointsToState.getObjectArrayTypes() End For Else For Each field in pointsToState.getReachableInstanceObjectFields(current.getClass()) Object value := field.read(current) Call AddObjectToWorkList(value) Add value.getClass() to pointsToState.getFieldValueTypes(field) End For End If End While Return reachableObjects End Function
综上所述,堆快照算法通过系统地遍历可达对象及其字段来高效地构建堆快照。这可确保图像堆中仅包含相关对象,从而优化本机图像的性能和内存占用。
结论
总而言之,堆快照过程在原生镜像的创建中起着至关重要的作用。通过系统地遍历可达对象及其字段,堆快照算法构建了一个对象图,该对象图表示可达对象从根指针(例如静态字段)的传递闭包。然后将该对象图作为图像堆嵌入到本机映像中,作为本机映像启动时的初始堆。
在整个过程中,算法依赖于分析点的状态来确定哪些对象和字段与包含在图像堆中相关。考虑由点分析标记为“已读”的对象和字段,而排除未标记的实体。此外,当遇到以前未见过的类型时,算法会将它们注册以便在点分析的后续迭代中传播。
总体而言,堆快照通过确保映像堆中仅包含必要的对象来优化本机映像的性能和内存使用情况。这种系统方法提高了本机图像执行的效率和可靠性。
今天关于《通过静态分析、映像初始化和堆快照提高性能》的内容介绍就到此结束,如果有什么疑问或者建议,可以在golang学习网公众号下多多回复交流;文中若有不正之处,也希望回复留言以告知!

- 上一篇
- 如何记录 Java 函数中应用程序状态的上下文错误信息

- 下一篇
- PHP 函数中递归如何防止栈溢出?
-
- 文章 · java教程 | 21分钟前 |
- 自定义HashMap排序方法全解析
- 386浏览 收藏
-
- 文章 · java教程 | 22分钟前 |
- Java深浅拷贝区别与实现方式
- 202浏览 收藏
-
- 文章 · java教程 | 27分钟前 |
- SpringBoot整合Kafka消息消费指南
- 319浏览 收藏
-
- 文章 · java教程 | 29分钟前 |
- ThreadLocal内存泄漏原因及解决方法
- 317浏览 收藏
-
- 文章 · java教程 | 53分钟前 |
- Java分布式追踪上下文传递方法
- 452浏览 收藏
-
- 文章 · java教程 | 1小时前 |
- MyBatis三种批量更新方法详解
- 341浏览 收藏
-
- 文章 · java教程 | 1小时前 |
- Java处理核磁数据与DICOM优化技巧
- 414浏览 收藏
-
- 文章 · java教程 | 1小时前 |
- SpringBoot错误提示优化技巧
- 159浏览 收藏
-
- 文章 · java教程 | 1小时前 |
- Resilience4j断路器配置全解析
- 304浏览 收藏
-
- 文章 · java教程 | 1小时前 |
- JavaSwingKeyListener失效原因与解决方法
- 363浏览 收藏
-
- 文章 · java教程 | 1小时前 |
- SpringCloudConfig高可用配置方案详解
- 369浏览 收藏
-
- 前端进阶之JavaScript设计模式
- 设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
- 542次学习
-
- GO语言核心编程课程
- 本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
- 511次学习
-
- 简单聊聊mysql8与网络通信
- 如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
- 498次学习
-
- JavaScript正则表达式基础与实战
- 在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
- 487次学习
-
- 从零制作响应式网站—Grid布局
- 本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
- 484次学习
-
- 千音漫语
- 千音漫语,北京熠声科技倾力打造的智能声音创作助手,提供AI配音、音视频翻译、语音识别、声音克隆等强大功能,助力有声书制作、视频创作、教育培训等领域,官网:https://qianyin123.com
- 179次使用
-
- MiniWork
- MiniWork是一款智能高效的AI工具平台,专为提升工作与学习效率而设计。整合文本处理、图像生成、营销策划及运营管理等多元AI工具,提供精准智能解决方案,让复杂工作简单高效。
- 177次使用
-
- NoCode
- NoCode (nocode.cn)是领先的无代码开发平台,通过拖放、AI对话等简单操作,助您快速创建各类应用、网站与管理系统。无需编程知识,轻松实现个人生活、商业经营、企业管理多场景需求,大幅降低开发门槛,高效低成本。
- 180次使用
-
- 达医智影
- 达医智影,阿里巴巴达摩院医疗AI创新力作。全球率先利用平扫CT实现“一扫多筛”,仅一次CT扫描即可高效识别多种癌症、急症及慢病,为疾病早期发现提供智能、精准的AI影像早筛解决方案。
- 187次使用
-
- 智慧芽Eureka
- 智慧芽Eureka,专为技术创新打造的AI Agent平台。深度理解专利、研发、生物医药、材料、科创等复杂场景,通过专家级AI Agent精准执行任务,智能化工作流解放70%生产力,让您专注核心创新。
- 201次使用
-
- 提升Java功能开发效率的有力工具:微服务架构
- 2023-10-06 501浏览
-
- 掌握Java海康SDK二次开发的必备技巧
- 2023-10-01 501浏览
-
- 如何使用java实现桶排序算法
- 2023-10-03 501浏览
-
- Java开发实战经验:如何优化开发逻辑
- 2023-10-31 501浏览
-
- 如何使用Java中的Math.max()方法比较两个数的大小?
- 2023-11-18 501浏览