首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

Quarkus本机可执行内部版本:高内存消耗

Quarkus 本机可执行内部版本:高内存消耗

基础概念

Quarkus 是一个为 Kubernetes 设计的 Java 框架,旨在简化 Java 应用程序的开发、部署和运行。Quarkus 支持多种编程模型,包括 RESTful Web 服务、GraphQL、gRPC 等。Quarkus 的本机可执行文件是通过 GraalVM 编译生成的,可以在没有 JVM 的情况下运行,从而提高启动速度和减少资源消耗。

相关优势

  1. 快速启动:本机可执行文件启动速度快,适用于无服务器架构和容器环境。
  2. 低资源消耗:相比传统的 JVM 运行时,GraalVM 编译的本机可执行文件通常有更低的内存和 CPU 消耗。
  3. 与 Kubernetes 集成:Quarkus 天然支持 Kubernetes,可以轻松部署和管理。
  4. 丰富的扩展生态:Quarkus 有大量的扩展,可以轻松集成各种服务和库。

类型

Quarkus 本机可执行文件主要有以下几种类型:

  • Standalone 可执行文件:独立运行的应用程序。
  • Kubernetes 部署:可以直接部署到 Kubernetes 集群中的应用程序。

应用场景

  • 微服务架构:Quarkus 适合构建轻量级的微服务。
  • 云原生应用:与 Kubernetes 集成良好,适合云原生环境。
  • 无服务器架构:快速启动和低资源消耗使其适合无服务器环境。

高内存消耗问题

原因分析

  1. GraalVM 编译开销:GraalVM 编译过程中可能会生成较大的本机镜像,导致内存消耗增加。
  2. 第三方库和扩展:某些第三方库或 Quarkus 扩展可能会增加内存消耗。
  3. 应用程序逻辑:应用程序本身的复杂性和数据处理量也会影响内存消耗。

解决方法

  1. 优化 GraalVM 编译配置
    • 使用 quarkus.native.additional-build-args 配置项来优化编译参数。
    • 使用 quarkus.native.additional-build-args 配置项来优化编译参数。
  • 精简依赖
    • 检查并移除不必要的依赖和扩展。
    • 检查并移除不必要的依赖和扩展。
  • 内存管理
    • application.properties 中配置 JVM 内存参数。
    • application.properties 中配置 JVM 内存参数。
  • 监控和分析
    • 使用工具如 Prometheus 和 Grafana 监控应用程序的内存使用情况。
    • 使用 Java 分析工具如 VisualVM 或 JProfiler 分析内存消耗。

参考链接

通过以上方法,可以有效减少 Quarkus 本机可执行文件的内存消耗,提高应用程序的性能和稳定性。

页面内容是否对你有帮助?
有帮助
没帮助

相关·内容

  • Java近期新闻:Grails 6.0、PrimeFaces 13.0、JUnit 5.10、GraalVM、新的 JEP 草案

    甲骨文(Oracle)的软件架构师 Maurizio Cimadamore 已经提交了 JEP Draft 8310626,外部函数和内存 API。该 JEP 提议在经过两轮孵化和三次预览后最终确定该特性:JEP 412,外部函数和内存 API(孵化阶段),在 JDK 17 中交付;JEP 419,外函数与内存 API(第二轮孵化),在 JDK 18 中交付;JEP 424,外部函数和内存 API(预览版),在 JDK 19 中发布;JEP 434,外部函数和内存 API(第二次预览),在 JDK 20 中发布;以及 JEP 442,外部函数和内存 API(第三次预览),将在即将发布的 JDK 21 中发布。自上一个版本发布以来的改进包括:一个新EnableNativeAccess 清单属性,允许可执行 JAR 中的代码在不使用--enableNativeAccess标志的情况下调用受限方法;允许客户端以编程方式构建 C 函数描述符,避免使用特定于平台的常量;改进了对本地内存中可变长度数组的支持;以及支持本地字符串中的多个字符集。

    03

    并发王座易主?Java 21 虚拟线程强势崛起,Go & Kotlin还稳得住吗 | 盘点

    据 JetBrain 前不久发布的 《2023 开发者生态系统现状》调研报告,在开发者主要采用的编程语言中,最受欢迎的分别是 Java、Python、JavaScript,Java 在 2023 年重夺第一名宝座,JavaScript 则在下降三个百分点后跌至第三;Rust 在 2023 年最受欢迎的编程语言中,创造了新的使用记录,其用户群在过去五年中稳步增长,有望凭借其严格的安全性和内存所有权机制取代 C++;此外,Rust 2023 年首次取代 Go 成为希望迁移到其他语言的开发者的首选,而且 Go 用户也是第一批准备采用 Rust 的人,JetBrains 数据表明,有六分之一的 Go 用户正在考虑采用 Rust。

    01

    笔记:追随云原生的Java

    但在微服务时代是提倡服务围绕业务能力(不同的语言适合不同的业务场景)而非技术来构建应用,不再追求实现上的一致,一个系统由不同语言、不同技术框架所实现的服务来组成是完全合理的。服务化拆分后,很可能单个微服务不再需要再面对数十、数百 GB 乃至 TB 的内存。有了高可用的服务集群,也无须追求单个服务要 7×24 小时不可间断地运行,它们随时可以中断和更新。不仅如此,微服务对镜像体积、内存消耗、启动速度,以及达到最高性能的时间等方面提出了新的要求。这两年的网红概念 Serverless(以及衍生出来的Faas) 也进一步增加这些因素的考虑权重,而这些却正好都是 Java 的弱项:哪怕再小的 Java 程序也要带着厚重的Rumtime(Vm和StandLibrary)——基于 Java 虚拟机的执行机制,使得任何 Java 的程序都会有固定的内存开销与启动时间,而且 Java 生态中广泛采用的依赖注入进一步将启动时间拉长,使得容器的冷启动时间很难缩短。 举两个例子。软件工业中已经出现过不止一起因 Java 这些弱点而导致失败的案例。如 JRuby 编写的 Logstash,原本是同时承担部署在节点上的收集端(Shipper)和专门转换处理的服务端(Master)的职责,后来因为资源占用的原因,被 Elstaic.co 用 Golang 的 Filebeat 代替了 Shipper 部分的职能。又如 Scala 语言编写的边车代理 Linkerd,作为服务网格概念的提出者,却最终被 Envoy 所取代,其主要弱点之一也是由于 Java 虚拟机的资源消耗所带来的劣势。 1.变革之火 1.1 Complie Native Code 显然,如果将字节码直接编译成可以脱离 Java 虚拟机的原生代码则可以解决所有问题。 如果真的能够生成脱离 Java 虚拟机运行的原生程序,将意味着启动时间长的问题能够彻底解决,因为此时已经不存在初始化虚拟机和类加载的过程。也意味着程序马上就能达到最佳的性能,因为此时已经不存在即时编译器运行时编译,所有代码都是在编译期编译和优化好的。同理,厚重的Runtime也不会出现在镜像中。 Java 并非没有尝试走过这条路。从GCJ到 Excelsior JET再到 GraalVM 中的 SubstrateVM 模块再到 2020 年中期建立的 Leyden 项目,都在朝着提前编译(Ahead-of-Time Compilation,AOT)生成原生程序这个目标迈进。Java 支持提前编译最大的困难在于它是一门动态链接的语言,它假设程序的代码空间是开放的(Open World),允许在程序的任何时候通过类加载器去加载新的类,作为程序的一部分运行。要进行提前编译,就必须放弃这部分动态性,假设程序的代码空间是封闭的(Closed World),所有要运行的代码都必须在编译期全部可知。 这一点不仅仅影响到了类加载器的正常运作,除了无法再动态加载外,反射(通过反射可以调用在编译期不可知的方法)、动态代理、字节码生成库(如 CGLib)等一切会运行时产生新代码的功能都不再可用——如果将这些基础能力直接抽离掉,Hello world 还是能跑起来,大部分的生产力工具都跑不起来,整个 Java 生态中绝大多数上层建筑都会轰然崩塌。随便列两个Case:Flink的SQL API会解析SQL并生成执行计划,这个时候会通过JavaCC动态生成类加载到代码空间中去;Spring也有类似的情况,当AOP通过动态代理的方式去生成相关逻辑时,本质还是在Runtime时生成代码并加载进去。 要获得有实用价值的提前编译能力,只有依靠提前编译器、组件类库和开发者三方一起协同才可能办到——可以参考Quarkus。 Quarkus和我们上述的方法如出一辙,以Dependency Inject为例:所有要运行的代码都必须在编译期全部可知,在编译期就推导出来相关的Bean,最后交给 GraalVM来运行。 1.2 Memory Access Efficiency Improvement Java 即时编译器的优化效果拔群,但是由于 Java“一切皆为对象”的前提假设,导致它在处理一系列不同类型的小对象时,内存访问性能很差。这点是 Java 在游戏、图形处理等领域一直难有建树的重要制约因素,也是 Java 建立 Valhalla 项目的目标初衷。 这里举个例子来说明此问题,如果我想描述空间里面若干条线段的集合,在 Java 中定义的代码会是这样的: public record Point(float x, float y, float z) {} public record Line(Point start, Point end) {} Line[] lines; 面向对象的内存布局中,对象标识符(Object Ident

    01
    领券