通过静态分析、映像初始化和堆快照提高性能
一分耕耘,一分收获!既然都打开这篇《通过静态分析、映像初始化和堆快照提高性能》,就坚持看下去,学下去吧!本文主要会给大家讲到等等知识点,如果大家对本文有好的建议或者看到有不足之处,非常欢迎大家积极提出!在后续文章我会继续更新文章相关的内容,希望对大家都有所帮助!
从整体结构到分布式系统世界,应用程序开发已经走过了漫长的道路。云计算和微服务架构的大规模采用极大地改变了服务器应用程序的创建和部署方式。我们现在拥有独立、单独部署的可立即投入使用的服务,而不是庞大的应用程序服务器
在需要时。
然而,区块上可能影响这种平稳运行的新玩家可能是“冷启动”。当第一个请求在新生成的工作线程上处理时,冷启动就会启动。这种情况需要在处理实际请求之前进行语言运行时初始化和服务配置初始化。与冷启动相关的不可预测性和执行速度较慢可能会违反云服务的服务级别协议。那么,如何应对这种日益增长的担忧呢?
本机映像:优化启动时间和内存占用
为了解决冷启动的低效率问题,我们开发了一种新颖的方法,涉及点分析、构建时的应用程序初始化、堆快照和提前 (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教程 | 17分钟前 |
- 手把手教你用Java搞定AWSLambda,轻松实现Serverless!
- 328浏览 收藏
-
- 文章 · java教程 | 1小时前 |
- Java类里都有啥?手把手教你搞定类的成员+访问控制
- 168浏览 收藏
-
- 文章 · java教程 | 1小时前 | java 画线
- Java绘图从零开始:手把手教你用代码画线
- 397浏览 收藏
-
- 文章 · java教程 | 1小时前 |
- Java基础不迷路:实例是什么?类与实例关系大揭秘
- 158浏览 收藏
-
- 文章 · java教程 | 1小时前 | java 排序 自然排序 Comparable compareTo
- Java中Comparable是什么?手把手教你实现自然排序
- 147浏览 收藏
-
- 文章 · java教程 | 2小时前 | java HTTPS SSL证书 keystore HttpsURLConnection
- Java实现HTTPS全解析:手把手教你搞定SSL证书配置
- 127浏览 收藏
-
- 文章 · java教程 | 2小时前 | shutdown 线程池 threadpoolexecutor Executors 拒绝策略
- JavaExecutors太顶了!手把手教你打造专属线程池
- 182浏览 收藏
-
- 文章 · java教程 | 3小时前 |
- Java类里到底有啥?手把手教你搞懂类成员+访问控制
- 210浏览 收藏
-
- 前端进阶之JavaScript设计模式
- 设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
- 542次学习
-
- GO语言核心编程课程
- 本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
- 508次学习
-
- 简单聊聊mysql8与网络通信
- 如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
- 497次学习
-
- JavaScript正则表达式基础与实战
- 在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
- 487次学习
-
- 从零制作响应式网站—Grid布局
- 本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
- 484次学习
-
- 茅茅虫AIGC检测
- 茅茅虫AIGC检测,湖南茅茅虫科技有限公司倾力打造,运用NLP技术精准识别AI生成文本,提供论文、专著等学术文本的AIGC检测服务。支持多种格式,生成可视化报告,保障您的学术诚信和内容质量。
- 96次使用
-
- 赛林匹克平台(Challympics)
- 探索赛林匹克平台Challympics,一个聚焦人工智能、算力算法、量子计算等前沿技术的赛事聚合平台。连接产学研用,助力科技创新与产业升级。
- 100次使用
-
- 笔格AIPPT
- SEO 笔格AIPPT是135编辑器推出的AI智能PPT制作平台,依托DeepSeek大模型,实现智能大纲生成、一键PPT生成、AI文字优化、图像生成等功能。免费试用,提升PPT制作效率,适用于商务演示、教育培训等多种场景。
- 106次使用
-
- 稿定PPT
- 告别PPT制作难题!稿定PPT提供海量模板、AI智能生成、在线协作,助您轻松制作专业演示文稿。职场办公、教育学习、企业服务全覆盖,降本增效,释放创意!
- 101次使用
-
- Suno苏诺中文版
- 探索Suno苏诺中文版,一款颠覆传统音乐创作的AI平台。无需专业技能,轻松创作个性化音乐。智能词曲生成、风格迁移、海量音效,释放您的音乐灵感!
- 99次使用
-
- 提升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浏览