java开发面试:AOT有什么优缺点/适用于什么场景/AOT和JIT的对比、逃逸分析和对象存储在堆上的关系、高并发中的集合有哪些问题

本文主要是介绍java开发面试:AOT有什么优缺点/适用于什么场景/AOT和JIT的对比、逃逸分析和对象存储在堆上的关系、高并发中的集合有哪些问题,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

JDK9引入了AOT编译模式。

AOT 有什么优点?适用于什么场景?

JDK 9 引入了一种新的编译模式 AOT(Ahead of Time Compilation) 。
和 JIT 不同的是,这种编译模式会在程序被执行前就将其编译成机器码,属于静态编译(C、 C++,Rust,Go 等语言就是静态编译)。

AOT 避免了 JIT 预热等各方面的开销,可以提高 Java 程序的启动速度。并且AOT 还能减少内存占用和增强 Java 程序的安全性,特别适合云原生场景。具体如下:

  • 启动速度:云原生应用通常需要快速启动和停止,以实现资源的动态分配和弹性伸缩。AOT编译可以显著减少应用程序的启动时间。
  • 资源效率:在云环境中,资源的使用效率非常重要。AOT减少了内存占用,因为它们不需要在运行时进行编译和优化,这有助于降低云服务的成本。
  • 安全性:AOT编译的代码通常是难以被反编译的,这增加了应用程序的安全性。在云环境中,安全性是一个重要的考虑因素,因为多个应用程序可能会共享相同的物理硬件。
  • 可预测性:AOT编译提供了更可预测的性能,因为所有的优化都在编译时完成,不会在运行时发生变化。这对于需要稳定性能的云服务来说非常重要。
  • 容器化和微服务:云原生应用通常采用容器化和微服务架构。AOT编译的应用程序可以更容易地打包到容器中,因为它们不需要在运行时进行额外的编译步骤。

AOT和JIT的对比和区别

JIT 与 AOT 两者的关键指标对比如下:
在这里插入图片描述
可以看出,AOT 的主要优势在于启动时间、内存占用和打包体积。JIT 的主要优势在于具备更高的极限处理能力,可以降低请求的最大延迟(这两点主要都是因为它可以动态优化代码还有逃逸分析机制)。

为什么不全部使用 AOT 呢?

既然 AOT 这么多优点,那为什么不全部使用这种编译方式呢?只能说 AOT 更适合当下的云原生场景,对微服务架构的支持也比较友好。除此之外,AOT 编译无法支持 Java 的一些动态特性,如反射、动态代理、动态加载等。然而,很多框架和库(如 最常用的Spring 和 Springboot)都用到了这些特性。如果只使用 AOT 编译,那就没办法使用这些框架和库了,为了支持类似的动态特性,所以选择使用 JIT 即时编译器。

逃逸分析和对象存储在堆上的关系。

为什么说是几乎所有对象实例都存在于堆中呢? 这是因为 HotSpot 虚拟机引入了 JIT 优化之后,会对对象进行逃逸分析,如果发现某一个对象并没有逃逸到方法外部(是否会作为参数传递给其他方法,或者被外部方法访问),那么就可能通过标量替换来实现栈上分配,而避免堆上分配内存。

标量替换实现栈上分配,避免堆上分配的意思是指:将对象分解成若干个标量(即基本数据类型的值,如 int、float 等),然后这些标量可以直接存储在栈上,而不是作为一个完整的对象存储在堆上。这样做的好处是,当方法调用结束时,这些标量会随着栈帧的销毁而自动释放,从而避免了在堆上进行分配和垃圾回收的开销。

高并发中的集合有哪些问题?

第一代线程安全集合类
Vector、Hashtable
是怎么保证线程安排的:使用synchronized修饰方法
缺点:效率低下

第二代线程非安全集合类
ArrayList、HashMap
线程不安全,但是性能好,用来替代Vector、.Hashtable
使用ArrayList、HashMap,需要线程安全怎么办呢?
Collections.synchronizedList(list);Collections.synchronizedMap(m);
底层使用synchronized代码块锁,虽然也是锁住了所有的代码,但是锁在方法里边,比锁在方法外边性能可以理解为稍有提高吧。毕竟进方法本身就要分配资源的

第三代线程安全集合类
在大量并发情况下如何提高集合的效率和安全呢?
java.util.concurrent.*
ConcurrentHashMap:
CopyOnWriteArrayList
CopyOnWriteArraySet:注意不是CopyOnWriteHashSet*

底层大都采用Lock锁(1.8的ConcurrentHashMap不使用Lock锁),保证安全的同时,性能也很高。

这篇关于java开发面试:AOT有什么优缺点/适用于什么场景/AOT和JIT的对比、逃逸分析和对象存储在堆上的关系、高并发中的集合有哪些问题的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1136930

相关文章

Spring Boot集成Druid实现数据源管理与监控的详细步骤

《SpringBoot集成Druid实现数据源管理与监控的详细步骤》本文介绍如何在SpringBoot项目中集成Druid数据库连接池,包括环境搭建、Maven依赖配置、SpringBoot配置文件... 目录1. 引言1.1 环境准备1.2 Druid介绍2. 配置Druid连接池3. 查看Druid监控

Java中读取YAML文件配置信息常见问题及解决方法

《Java中读取YAML文件配置信息常见问题及解决方法》:本文主要介绍Java中读取YAML文件配置信息常见问题及解决方法,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要... 目录1 使用Spring Boot的@ConfigurationProperties2. 使用@Valu

创建Java keystore文件的完整指南及详细步骤

《创建Javakeystore文件的完整指南及详细步骤》本文详解Java中keystore的创建与配置,涵盖私钥管理、自签名与CA证书生成、SSL/TLS应用,强调安全存储及验证机制,确保通信加密和... 目录1. 秘密键(私钥)的理解与管理私钥的定义与重要性私钥的管理策略私钥的生成与存储2. 证书的创建与

浅析Spring如何控制Bean的加载顺序

《浅析Spring如何控制Bean的加载顺序》在大多数情况下,我们不需要手动控制Bean的加载顺序,因为Spring的IoC容器足够智能,但在某些特殊场景下,这种隐式的依赖关系可能不存在,下面我们就来... 目录核心原则:依赖驱动加载手动控制 Bean 加载顺序的方法方法 1:使用@DependsOn(最直

SpringBoot中如何使用Assert进行断言校验

《SpringBoot中如何使用Assert进行断言校验》Java提供了内置的assert机制,而Spring框架也提供了更强大的Assert工具类来帮助开发者进行参数校验和状态检查,下... 目录前言一、Java 原生assert简介1.1 使用方式1.2 示例代码1.3 优缺点分析二、Spring Fr

Android kotlin中 Channel 和 Flow 的区别和选择使用场景分析

《Androidkotlin中Channel和Flow的区别和选择使用场景分析》Kotlin协程中,Flow是冷数据流,按需触发,适合响应式数据处理;Channel是热数据流,持续发送,支持... 目录一、基本概念界定FlowChannel二、核心特性对比数据生产触发条件生产与消费的关系背压处理机制生命周期

java使用protobuf-maven-plugin的插件编译proto文件详解

《java使用protobuf-maven-plugin的插件编译proto文件详解》:本文主要介绍java使用protobuf-maven-plugin的插件编译proto文件,具有很好的参考价... 目录protobuf文件作为数据传输和存储的协议主要介绍在Java使用maven编译proto文件的插件

Java中的数组与集合基本用法详解

《Java中的数组与集合基本用法详解》本文介绍了Java数组和集合框架的基础知识,数组部分涵盖了一维、二维及多维数组的声明、初始化、访问与遍历方法,以及Arrays类的常用操作,对Java数组与集合相... 目录一、Java数组基础1.1 数组结构概述1.2 一维数组1.2.1 声明与初始化1.2.2 访问

Javaee多线程之进程和线程之间的区别和联系(最新整理)

《Javaee多线程之进程和线程之间的区别和联系(最新整理)》进程是资源分配单位,线程是调度执行单位,共享资源更高效,创建线程五种方式:继承Thread、Runnable接口、匿名类、lambda,r... 目录进程和线程进程线程进程和线程的区别创建线程的五种写法继承Thread,重写run实现Runnab

Java 方法重载Overload常见误区及注意事项

《Java方法重载Overload常见误区及注意事项》Java方法重载允许同一类中同名方法通过参数类型、数量、顺序差异实现功能扩展,提升代码灵活性,核心条件为参数列表不同,不涉及返回类型、访问修饰符... 目录Java 方法重载(Overload)详解一、方法重载的核心条件二、构成方法重载的具体情况三、不构