JVM——即时编译

news2025/5/10 6:34:45

分层编译模式:动态平衡启动速度与执行效率

分层编译是现代JVM(如HotSpot、GraalVM)实现高性能的核心策略之一,其核心思想是根据代码的执行热度动态选择不同的编译层次,实现启动速度与运行效率的最佳平衡。以HotSpot虚拟机为例,其分层编译架构通常包含以下五个层次:

  1. 第0层:纯解释执行

    特点:完全依赖解释器逐行执行字节码,不开启任何性能监控(Profiling)。

    适用场景:程序启动初期,快速加载并执行代码,避免编译延迟。

    优势:启动速度极快,内存占用低,适合资源受限的嵌入式系统或短生命周期应用。

  2.  第1层:C1基础编译

    特点:使用客户端编译器(C1)将字节码编译为本地代码,执行简单稳定的优化(如方法内联、常量传播),但不收集性能数据。

    触发条件:方法调用次数或循环回边次数超过默认阈值(如1500次)。

    优势:编译速度快,能在程序启动后迅速提升部分代码的执行效率。

  3. 第2层:C1有限监控编

    特点:仍使用C1编译器,但开启方法调用次数和循环回边次数的统计。

    触发条件:在第1层基础上,进一步收集有限的性能数据,为后续优化提供依据。

    作用:初步识别热点代码,为更高层次的编译做准备。

  4. 第3层:C1全量监控编译

    特点:C1编译器收集完整的性能数据,包括分支跳转频率、虚方法调用版本等。

    触发条件:方法调用次数或循环回边次数达到更高阈值(如10000次)。

    作用:为服务端编译器(C2)提供详细的Profiling信息,支持更复杂的优化。

  5. 第4层:C2深度优化编译

    特点:使用服务端编译器(C2)进行激进优化,包括全局优化、循环展开、向量化等。

    触发条件:在第3层收集足够数据后,C2编译器介入生成高度优化的机器码。

    优势:生成代码执行效率高,适合长时间运行的服务端应用。

分层编译的协同机制

  • 动态调整:各层次之间并非固定,JVM会根据代码热度动态调整编译层次。例如,当某个方法的执行频率下降时,可能会回退到较低层次以节省资源。

  • 代码缓存管理:分层编译需要更大的代码缓存(默认240MB),以存储不同层次的编译结果。若缓存不足,JVM会发出警告并可能降级编译策略。

  • GraalVM的改进:GraalVM引入Graal编译器作为C2的替代者,采用更先进的中间表示(Sea-of-Nodes)和优化算法,支持部分逃逸分析、激进预测性优化等,在某些场景下性能超越C2。

分层编译的典型应用场景

  • 微服务架构:启动时通过C1快速编译,快速响应请求;运行稳定后,C2对核心业务逻辑进行深度优化,提升吞吐量。

  • 大数据处理:循环密集型任务(如MapReduce)通过OSR编译在运行时动态优化,显著减少执行时间。

  • 移动端应用:结合ART的AOT编译与JIT动态优化,平衡安装速度与运行性能。

即时编译的触发:热点代码的精准识别

即时编译的触发依赖于热点代码的探测机制。HotSpot采用基于计数器的热点探测方法,为每个方法维护两个计数器:

  1. 方法调用计数器(Invocation Counter)

    作用:统计方法被调用的次数。

    阈值:默认1500次(可通过-XX:CompileThreshold调整)。

    触发条件:当调用次数超过阈值时,触发标准即时编译(即整个方法被编译)。

  2. 回边计数器(Back Edge Counter)

    作用:统计循环体的执行次数(回边指循环边界的跳转指令)。

    阈值计算:InterpreterBackwardBranchLimit = (CompileThreshold * (OnStackReplacePercentage - InterpreterProfilePercentage)) / 100,默认约10700次。

    触发条件:当循环次数超过阈值时,触发栈上替换(OSR)编译,仅优化循环体部分。

热点探测的优化策略

  • 自适应调整:JVM会根据程序运行情况动态调整计数器阈值。例如,若某个方法调用频繁但执行时间短,可能降低阈值以提前编译。

  • 分层触发:不同编译层次的触发条件不同。例如,C1编译可能在调用次数达到1500次时触发,而C2编译需要更高的阈值(如10000次)。

  • OSR编译的特殊性:OSR编译允许在方法执行过程中动态替换栈帧,避免重新编译整个方法的开销。例如,当循环次数超过阈值时,JVM会将循环体编译为本地代码,并替换当前栈帧,后续迭代直接执行优化后的代码。

热点探测的实现细节

  • 安全点(Safepoint):编译操作必须在安全点进行,此时所有线程暂停,确保状态一致。安全点通常位于方法调用、循环回边等位置。

  • 异步编译:热点代码的编译由后台线程异步执行,避免阻塞主线程。例如,C1和C2编译器分别由不同的线程池处理。

  • 阈值调整参数:通过-XX:Tier3CompileThreshold等参数可定制各层次的触发条件,以适应不同应用的需求。

OSR编译:循环优化的核心技术

栈上替换(On-Stack Replacement,OSR)是即时编译中针对循环优化的关键技术,允许在循环执行过程中动态替换为优化后的本地代码,而无需重新编译整个方法。

OSR的触发条件

循环次数阈值:当循环回边次数超过InterpreterBackwardBranchLimit(默认约10700次)时触发。

编译可行性:JVM需确保循环体的编译结果可以无缝替换当前栈帧,包括局部变量和操作数栈的状态保存与恢复。

OSR的实现步骤

状态捕获:解释器在执行循环时,记录当前栈帧的局部变量、操作数栈和程序计数器(PC)。

代码生成:C1或C2编译器针对循环体生成优化后的本地代码,并生成一个OSR入口点。

栈帧替换:当循环再次执行到入口点时,JVM将解释执行的栈帧替换为编译后的栈帧,后续迭代直接执行本地代码。

状态恢复:编译后的代码需根据捕获的状态恢复局部变量和操作数栈,确保执行连续性。

OSR的关键挑战

局部变量映射:解释执行的局部变量可能存储在栈或寄存器中,编译后的代码需正确映射这些变量的位置。

异常处理:OSR编译后的代码需处理可能抛出的异常,并与解释执行的异常处理逻辑兼容。

代码缓存管理:OSR编译生成的代码需存储在代码缓存中,需合理分配空间以避免缓存溢出。

OSR的性能影响

优化效果:OSR可显著减少循环的执行时间。例如,在某电商系统中,循环密集型任务通过OSR优化后,吞吐量提升28%。

编译开销:OSR编译需要额外的时间和资源,可能对启动性能产生轻微影响。

调试复杂性:OSR导致的代码替换可能使调试工具(如断点)的行为变得复杂,需特殊处理。

Profiling:优化决策的核心依据

Profiling(性能分析)是即时编译的核心支撑技术,通过收集代码执行时的动态数据,指导编译器进行针对性优化。HotSpot的Profiling主要包括分支Profile和类型Profile。

分支Profile的收集与应用

收集方式

  • 静态分析:在解释执行或C1编译阶段,统计条件跳转指令的分支频率。

  • 动态监控:C1编译后的代码在执行时,实时记录分支跳转的历史数据。

优化策略

  • 分支预测:根据历史数据预测分支走向,减少流水线冲刷。例如,若某分支90%的时间为真,编译器可优先执行该路径。

  • 分支消除:对于始终为真或假的分支,直接移除条件判断。例如,if (true) { ... }可简化为直接执行代码块。

  • 代码重排:将高频执行的基本块(Basic Block)相邻放置,提高CPU缓存命中率。例如,使用BOLT工具根据分支频率重排代码布局,减少缓存未命中。

类型Profile的收集与应用

收集方式

  • 虚方法调用记录:在解释执行或C1编译阶段,记录虚方法调用的实际类型。

  • 动态类型监控:C1编译后的代码在执行时,统计方法调用的参数类型分布。

优化策略

  • 类型特化:根据类型Profile生成特定类型的优化代码。例如,若List的实现类90%为ArrayList,编译器可将List.get()调用直接替换为ArrayList.get(),避免虚方法开销。

  • 去虚拟化:对于类型单一的虚方法调用,直接内联具体实现,消除动态分派的开销。

  • 内联决策:结合类型Profile调整内联策略。例如,若某方法的参数类型变化频繁,可能选择不内联以避免去优化风险。

Profiling的实现细节

数据存储:分支Profile和类型Profile存储在JVM的内部数据结构中,如ProfileData对象。

数据更新:Profiling数据在代码执行时动态更新,确保编译器获取最新的执行信息。

优化粒度:Profiling可精确到方法、循环或基本块级别,支持细粒度的优化决策。

Profiling的局限性

数据滞后性:Profiling数据反映的是历史执行情况,可能与当前执行路径不完全匹配。

空间开销:大量的Profiling数据需要占用内存,可能影响JVM的资源分配。

去优化风险:基于Profiling的优化假设可能不成立(如类型变化),导致去优化操作,增加运行时开销。

基于分支Profile的优化:提升条件语句效率

分支预测和优化是提升程序性能的关键手段,尤其在循环和条件判断密集的代码中。基于分支Profile的优化主要包括以下策略:

分支预测优化

静态预测

  • Always Taken:假设所有分支都跳转,适用于循环条件。

  • Backward Taken, Forward Not Taken (BTFN):假设向后跳转的分支(如循环)总是跳转,向前跳转的分支不跳转。

动态预测

  • 两比特计数器(Two-bit Counter):记录分支最近两次的执行结果,预测未来走向。例如,若分支连续两次跳转,则预测下次跳转。

  • 全局历史表(Global History Table):结合全局分支历史进行预测,适用于长距离依赖的分支。

分支消除与简化

常量条件:若条件表达式在编译时已知结果,直接移除条件判断。例如:

if (false) {
    // 永远不会执行的代码
}

编译器可直接删除该分支。

条件合并:将多个条件判断合并为一个,减少分支数量。例如:

if (a > 0) {
    if (b < 10) {
        // 代码块
    }
}

可优化为:

if (a > 0 && b < 10) {
    // 代码块
}

代码重排与布局优化

基本块重排:将高频执行的基本块相邻放置,提高CPU缓存命中率。例如,将if分支的真路径和假路径按执行频率排序。

循环展开:通过增加循环体的指令数量,减少循环次数和分支判断。例如,将循环展开两次:

for (int i = 0; i < n; i += 2) {
    process(i);
    process(i + 1);
}

减少循环条件的判断次数。

预测执行(Speculative Execution)

分支预判:在分支条件未确定前,提前执行可能的路径。例如,若预测分支为真,提前执行真路径的指令,并在条件确定后验证结果。

推测加载:提前加载可能使用的数据到缓存,减少内存访问延迟。例如,在循环中提前加载下一次迭代所需的数据。

实际应用案例

数据库查询优化:在SQL查询引擎中,根据分支Profile调整执行计划,选择更高效的索引或扫描方式。

游戏引擎:在碰撞检测算法中,通过分支预测和代码重排提升实时响应性能。

金融交易系统:在高频交易场景中,通过分支消除和预测执行减少延迟,提升吞吐量。

基于类型Profile的优化:消除动态分派开销

类型Profile的优化主要针对虚方法调用和动态类型绑定,通过减少运行时的动态分派开销,提升执行效率。以下是主要优化策略:

类型特化(Type Specialization)

原理:根据类型Profile生成特定类型的优化代码。例如,若某虚方法List.get(int)的调用中,90%的List实例为ArrayList,编译器可生成ArrayList.get(int)的直接调用,避免虚方法开销。

实现步骤

  1. 收集类型Profile,统计方法调用的实际类型分布。

  2. 为高频类型生成特化代码,并保留通用版本作为后备。

  3. 在调用点插入类型检查,若实际类型匹配特化版本,则执行优化代码;否则回退到通用版本。

去虚拟化(Devirtualization)

原理:对于类型单一的虚方法调用,直接内联具体实现,消除动态分派。例如,若某虚方法Animal.sound()的调用中,所有Animal实例均为Dog,编译器可将调用替换为Dog.sound()的直接调用。

触发条件

  • 类型Profile显示方法调用的实际类型高度集中。

  • 方法体较小,内联收益大于开销。

内联优化与类型Profile结合

动态内联:根据类型Profile调整内联策略。例如,若某方法的参数类型变化频繁,可能选择不内联以避免去优化;若类型稳定,则积极内联。

类型驱动的内联:内联时考虑参数类型,生成特定类型的内联代码。例如,List.add(Object)可根据实际参数类型内联为ArrayList.add(String)LinkedList.add(Integer)

类型继承结构优化

常量传播:若父类方法被覆盖,且子类方法在运行时占主导地位,编译器可将父类方法的调用替换为子类实现。

字段内联:若子类字段未被覆盖,可直接访问子类字段,避免动态查找。

实际应用案例

ORM框架:在Hibernate中,根据类型Profile优化对象加载时的反射调用,减少动态代理的开销。

容器类库:在Java集合框架中,根据类型Profile优化Iterator的实现,例如将ArrayList的迭代器直接替换为数组访问。

深度学习框架:在TensorFlow中,根据张量类型Profile优化算子选择,例如针对float32int8数据生成不同的计算内核。

去优化:应对优化假设的失效

去优化(Deoptimization)是即时编译中的关键机制,当优化假设不成立时,将代码从编译执行回退到解释执行或重新编译,确保程序正确性。以下是去优化的常见场景和实现机制:

去优化的触发条件

类型变化:若虚方法调用的实际类型超出类型Profile的预期,导致去虚拟化失败。

分支预测错误:若分支执行路径与Profile数据不符,导致激进优化失效。

加载新类:类加载后,方法的继承结构发生变化,影响已编译代码的逻辑。

罕见陷阱(Uncommon Trap):某些异常情况(如数组越界)在优化代码中未处理,需回退到解释执行。

去优化的实现步骤

  1. 状态保存:在编译代码中插入去优化点,保存当前栈帧的局部变量、操作数栈和程序计数器。

  2. 回退逻辑:当触发条件满足时,JVM将执行权转移到解释器,并根据保存的状态恢复执行。

  3. 重新编译:若去优化频繁发生,JVM可能重新编译代码,调整优化策略。

去优化的性能影响

单次开销:去优化操作本身会带来一定的性能损失,通常在微秒级。

频繁去优化:若代码频繁触发去优化,可能导致性能下降。例如,动态类型语言(如JavaScript)中,类型变化频繁可能导致去优化成为主要开销。

优化策略调整:JVM会根据去优化的频率动态调整编译策略,例如降低优化级别或增加Profiling的频率。

去优化的案例分析

逃逸分析失效:若对象的作用域超出预期(如被外部线程访问),逃逸分析的优化(如栈上分配)失效,需回退到堆分配。

虚方法调用类型变化:若某个虚方法的调用在运行时出现新的子类,导致去虚拟化失败,需回退到动态分派。

激进优化假设不成立:例如,编译器假设某分支永远不会执行,但实际执行时触发该分支,导致去优化。

减少去优化的策略

限制动态类型使用:在静态类型语言中,避免过度使用反射和动态代理。

预热阶段优化:在程序启动后,主动执行关键路径代码,收集足够的Profiling数据,减少运行时去优化。

参数调优:通过-XX:DeoptimizationWorkers等参数调整去优化线程数,平衡响应速度与资源消耗。

从JIT到AI驱动的编译优化

1. 即时编译的发展历程

  • 早期阶段(1990s-2000s):以HotSpot的C1/C2编译器为代表,实现基本的分层编译和热点优化。

  • 中期阶段(2010s):GraalVM的出现,引入多语言支持和更先进的优化算法(如部分逃逸分析)。

  • 近期阶段(2020s):AI技术的应用,如机器学习模型用于编译决策,硬件协同优化(如GPU加速编译)。

2. 现有技术的局限性

  • 优化策略的静态性:现有优化策略基于历史数据,无法实时适应动态变化的运行环境。

  • 硬件协同不足:JIT编译器对新型硬件(如NPU、FPGA)的支持有限,未充分发挥异构计算的潜力。

  • 去优化的开销:频繁的去优化可能抵消部分编译优化的收益,尤其在动态语言中。

3. 未来发展趋势

  • AI驱动的编译优化

    • 机器学习模型:使用深度学习预测热点代码、优化策略,提升编译决策的准确性。例如,小米的AI编译器利用强化学习优化代码布局,启动速度提升60%。

    • 自动调优:根据硬件状态(如CPU负载、内存带宽)动态调整编译策略,实现自适应优化。

  • 硬件协同优化

    • 异构计算:将计算任务分配到CPU、GPU、NPU等不同设备,JIT编译器生成跨平台的优化代码。例如,昇思MindSpore通过张量重排布和自动微分支持GPU加速编译。

    • 近存计算:结合HBM高带宽内存和存算一体架构,减少数据搬运能耗,提升计算密集型任务的效率。

  • 更高效的去优化机制

    • 增量编译:仅重新编译受影响的代码部分,减少编译开销。

    • 预测性去优化:通过机器学习预测可能触发去优化的场景,提前调整优化策略。

  • 多语言统一编译

    • GraalVM的演进:支持更多语言(如Rust、Python)的即时编译,实现跨语言的无缝优化。

    • 泛在智能:在边缘设备上实现轻量级JIT编译,结合AI Agent实现端云协同优化。

总结

即时编译是现代高性能计算的基石,其技术体系从分层编译、热点探测到去优化,不断演进以适应新的应用场景和硬件架构。未来,随着AI和硬件技术的发展,JIT编译将更加智能化、自适应化,实现从“代码优化”到“系统级协同优化”的跨越。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2372087.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

flutter 的热更新方案shorebird

Flutter 热修复&#xff08;Shorebird&#xff09;_flutter shorebird-CSDN博客 Preview Locally | ShorebirdLearn how to preview an existing release of your application.https://docs.shorebird.dev/code-push/preview/ 控制台&#xff1a; Shorebird Console 文档&…

创建型模式:抽象工厂(Abstract Factory)模式

一、概念与核心思想​ 抽象工厂(Abstract Factory)模式是创建型设计模式的重要成员,它提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。该模式将对象的创建逻辑封装在抽象工厂及其具体实现类中,客户端通过抽象工厂接口获取所需的对象族,实现对象创…

PDF文档解析新突破:图表识别、公式还原、手写字体处理,让AI真正读懂复杂文档!

要想LLM大模型性能更佳&#xff0c;我们需要喂给模型看得懂的高质量数据。那有没有一种方法&#xff0c;能让我们把各种文档“读懂”&#xff0c;再喂给大模型使用呢&#xff1f; 如果你用传统OCR工具直接从PDF中提取文本&#xff0c;结果往往是乱序、缺失、格式错乱。因为实际…

Redis 主从复制集群搭建教程

目录 为什么要搭建 Redis 主从复制集群&#xff1f;搭建 Redis 主从复制集群前提条件步骤一&#xff1a;创建 Docker 网络步骤二&#xff1a;启动 Redis 主节点步骤三&#xff1a;启动 Redis 从节点步骤四&#xff1a;验证复制状态步骤五&#xff1a;使用 Python 连接 Redis 集…

共模电感在开关电源交流侧的应用原理与原因

在开关电源的设计中&#xff0c;共模电感是一个关键的电子元件&#xff0c;它常被连接在开关电源的交流一侧。然而&#xff0c;很多人虽然对共模电感并不陌生&#xff0c;但对于它为何要接在交流一侧&#xff0c;可能并没有深入理解。接下来&#xff0c;我们将详细探讨共模电感…

MySQL——七、索引

优势&#xff1a;极高查询效率&#xff1b;极高排序效率 劣势&#xff1a;占用磁盘空间&#xff1b;降低更新表的速度&#xff08;可忽略&#xff0c;磁盘相对便宜&#xff1b;增删改比例较小&#xff09; 索引结构 MYSQL的索引是在存储引擎层实现的&#xff0c;不同的存储引…

HTML应用指南:利用POST请求获取全国德邦快递服务网点位置信息

德邦快递作为中国领先的综合性物流服务提供商,自1996年成立以来,始终致力于为客户提供高效、安全的大件快递及其他物流解决方案。德邦快递凭借其强大的直营模式、“最后一公里”的优质服务以及对科技的持续投入,在竞争激烈的物流市场中占据了重要位置。特别是在大件快递领域…

高级可视化图表分析实践——以《大侠立志传》武器系统为例

高级可视化图表分析实践——以《大侠立志传》武器系统为例 引言武器类型分布矩形树图结论 不同品质/类别武器的攻击力分布情况蜂群图分析结论 武器来源桑基图分析结论 武器附加属性词云图分析结论 不同品级武器装备熟练度要求/特质要求离散热力图结论品质与熟练度的正相关性品质…

RoPE长度外推:外插内插

RoPE:假定 α \alpha α是定值 其中一半位置是用cos表示的 cos ⁡ ( k α − 2 i d ) \cos(k\alpha^{-\frac{2i}{d}}) cos(kα−d2i​)(另一半是sin)(d是词嵌入维度) 当太长如何解决: 1 直接不管—外插 缺点:超过一定长度性能急剧下降。(较大时&#xff0c;对应的很多位置编码…

【C++进阶】第2课—多态

文章目录 1. 认识多态2. 多态的定义和实现2.1 构成多态的必要条件2.2 虚函数2.3 虚函数的重写或覆盖2.4 协变(了解)2.5 析构函数的重写2.6 override和final关键字2.7 重载、重写、隐藏对比 3. 纯虚函数和抽象类4. 多态原理4.1 虚函数表指针4.2 多态的实现4.3 静态绑定和动态绑定…

RSS 2025|斯坦福提出「统一视频行动模型UVA」:实现机器人高精度动作推理

导读 在机器人领域&#xff0c;让机器人像人类一样理解视觉信息并做出精准行动&#xff0c;一直是科研人员努力的方向。今天&#xff0c;我们要探讨的统一视频行动模型&#xff08;Unified Video Action Model&#xff0c;UVA&#xff09;&#xff0c;就像给机器人装上了一个“…

第十六届蓝桥杯B组第二题

当时在考场的时候这一道题目 无论我是使用JAVA的大数&#xff08;BIGTHGER&#xff09;还是赛后 使用PY 都是没有运行出来 今天也是突发奇想在B站上面搜一搜 看了才知道这也是需要一定的数学思维 通过转换 设X来把运算式精简化 避免运行超时 下面则是代码 public class lanba…

Android Studio 中使用 SQLite 数据库开发完整指南(Kotlin版本)

文章目录 1. 项目准备1.1 创建新项目1.2 添加必要依赖 2. 数据库设计3. 实现数据库3.1 创建实体类 (Entity)3.2 创建数据访问对象 (DAO)3.3 创建数据库类 4. 创建 Repository5. 创建 ViewModel6. 实现 UI 层6.1 创建笔记列表 Activityactivity_notes_list.xmlNotesListActivity…

Spring 框架实战:如何实现高效的依赖注入,优化项目结构?

Spring 框架实战&#xff1a;如何实现高效的依赖注入&#xff0c;优化项目结构&#xff1f; 在当今的 Java 开发领域&#xff0c;Spring 框架占据着举足轻重的地位。而依赖注入作为 Spring 的核心概念之一&#xff0c;对于构建高效、灵活且易于维护的项目结构有着关键作用。本…

C++ learning day 01

目录 1. iostream : 2.第一个C++程序 3. 执行过程以及以上例子详解(以上例子为参考) 1. iostream : 全称: input/output stream library 作用: 用于处理输入输出操作 2.第一个C++程序 #include <iostream>int main() {std::cout << "Hello World! &qu…

李沐《动手学深度学习》 | 多层感知机

文章目录 感知机模型《深度学习入门》的解释训练感知机损失函数的选择感知机的收敛定理&#xff1a;什么时候能够停下来&#xff0c;是不是真的可以停下来感知机的不足 多层感知模型案例引入隐藏层从线性到非线性单隐藏层-单分类案例多隐藏层 激活函数softmax函数溢出的问题 多…

vue教程(vuepress版)

Vue 完全指南 项目介绍 这是一个系统化的 Vue.js 学习教程&#xff0c;采用循序渐进的方式&#xff0c;帮助开发者从零开始掌握 Vue 开发技能。 教程特点 循序渐进: 从 Vue 基础概念开始&#xff0c;逐步深入到高级特性&#xff0c;适合不同层次的开发者学习实战驱动: 结合…

【网络原理】深入理解HTTPS协议

本篇博客给大家带来的是网络原理的知识点,本篇解释了为什么有HTTP还要发展HTTPS协议. &#x1f40e;文章专栏: JavaEE初阶 &#x1f680;若有问题 评论区见 ❤ 欢迎大家点赞 评论 收藏 分享 如果你不知道分享给谁,那就分享给薯条. 你们的支持是我不断创作的动力 . 王子,公主请阅…

Linux上将conda环境VLLM服务注册为开机自启

这里写目录标题 一、Systemd服务方式1、编写启动脚本2、保存脚本并赋予权限3、创建 systemd 服务单元文件3、 启用并测试服务4、停止systemd服务 二、Crontab方式1、编辑crontab文件2、添加开机启动任务 参考链接 项目需要vllm进行模型支撑&#xff0c;所以需要做成开机自启保证…

k8s的pod挂载共享内存

k8s的pod挂载共享内存&#xff0c;限制不生效问题&#xff1a; 注&#xff1a;/dev/shm 是 Linux 系统中用于共享内存的特殊路径。通过将 emptyDir 的 medium 设置为 Memory&#xff0c;可以确保 /dev/shm 正确地挂载到一个基于内存的文件系统&#xff0c;从而实现高效的共享内…