当前位置: 首页 > news >正文

面试之JVM

类的生命周期

加载、链接、初始化(是类的初始化)、使用(对象的初始化)、卸载(GC)

链接:验证、准备、解析

类加载

JDK9的升级点:扩展类加载器改成了平台类加载器。 java中很多的包分成不同的模块,这些模块指定了类加载器。

类加载机制的特性:

保证加载的类的安全性、唯一性

对象创建过程

类加载判断,没有的话,先加载类

分配内存:指针碰撞or空闲列表。  竞争CAS+TLAB

初始化:设置默认值

设置对象头:

执行<init>方法

字节码文件中:

<init>是对 对象级别的变量和非静态代码块进行初始化

<cinit> 是对静态变量或静态代码块来初始化

对象内存分配方式

指针碰撞  空闲列表

是由垃圾回收器决定使用哪种。 CMS是空闲列表,较少STW

对象创建线程竞争

TLAB : thread local allocation buffer

CAS:硬件提供的原子指令, 分配内存时是使用CAS原子性的更新内存分配指针。

对象内存布局

对象在内存中的布局:对象头(Mark Word、Klass Pointer 、数组长度) 、实例数据、对齐填充。

对象的大小必须是8字节的倍数。

内存泄露原因

  • 静态集合
  • 静态类型的单例
  • 数据库连接、IO 、Socket连接, 不再使用的时候,需要调用close方法关闭,否则相应的对象Connection、Statement、ResultSet、Session等不会被GC回收。
  • 变量不合理的作用域, 作用域大于其使用范围
  • ThreadLocal变量, 线程池中使用这种类型变量

三色标记

在CMS垃圾收集器中,实现了真正的并发,指的是gc线程和用户线程并发执行,三色标记是用于这种并发下的标记。

优点:

  • 减少STW
  • 避免了GC Root可达性分析方法中的重复标记问题,提升标记阶段的效率

并发标记存在问题:多标和漏标, 多标产生浮动垃圾,下次gc回收; 漏标采用增量更新或原始快照的方式解决, CMS 增量更新, G1 原始快照

G1垃圾回收器

  1. 内存布局
  2. 垃圾回收算过程
  3. 垃圾回收算法:复制,整体标记整理
  4. 特点:要求大内存, 可以配置最大停顿时间,会按照这个时间指定垃圾回收计划, 目的是减少STW的时间
  5. 对象在一个Region分配内存,采用指针碰撞的方式

对象一定分配在堆上吗

逃逸分析 + 热点代码  -》 栈上分配

  • 减轻gc压力
  • 确定了变量不会逃逸出线程,就不存在锁竞争问题,会做锁消除的优化
  • 标量替换

JVM监控

JVM参数

  1. 内存大小
  2. 垃圾回收器
  3. 并行垃圾收集器参数
  4. gc打印配置
  5. 。。。。。

线上服务器CPU占用过高

进程 -》 线程 -》 报错内容

1. top   找cpu占用高的进程

2. top -H -p pid 找到对应的线程pid

3.  printf '0x%x\n' 线程pid (线程pid的十六进制)

4. jstack 进程pid | grep 16进制线程pid -A20    :  展示线程的堆栈信息

频繁minor gc

1. jstat -gc pid 1000 10   确认是否是频繁minor gc

2. 结合Full GC来看,年轻代是否设置的太小

3. 代码中是否产生很多无效对象

频发Full GC

JVM调优工具-CSDN博客

1. jstat  确定当前young gc和full gc的频率

2. 查看当前JVM参数, 结合实际业务情况,确定参数的配置是否合理。比如,当前业务是否产生大对象、是否有长期存活的对象、是否Survivor区太小触发动态年龄判断、老年代空间担保机制?在上述分析的基础上,调整JVM参数做测试

对象动态年龄判断机制导致的full gc较为频繁可以先试着优化下JVM参数,把年轻代适当调大点
触发老年代担保机制,可能导致full gc次数比young gc次数多


3. 借助jmap命令查看内存中的对象,大概确定是什么对象在频繁gc

jmap -histo <进程号>

4. jstack  确定这个对象在代码哪里产生的

5. 考虑是否出现了内存泄露

6. 接口JVM工具分析dump文件

OOM定位

OOM原因:

排查, 分析dump文件: 

OOM会导致JVM退出吗

子线程OOM 不会导致JVM退出,无论子线程是否捕获异常。 如果子线程未捕获异常,这个子线程会结束,因为此时还有主线程在运行,JVM不会退出。

主线程OOM,如果捕获了这个异常,不会退出;如果未捕获,会退出,这是因为JVM中没有其他非守护线程来保持程序的执行。

常量池

Class常量池:Class二级制文件的一部分,Class常量池中的内容包括

运行时常量池:Class文件被加载在JVM中, Class常量池就称之为运行时常量池了。

字符串常量池:是运行时常量池的一部分, jdk1.6及之前都是存在方法区的, jdk1.7及之后,字符串常量池移动到了堆内存中存储。

JVM退出的情况

GC是在任意时刻都能进行的吗

GC只能在安全点才能执行,JVM中, 安全点是程序执行的某些特殊位置。安全点的设置确保了当线程暂停时,程序的状态是可知的、一致的。

作用:

1. 垃圾收集

        垃圾回收时,JVM要暂停所有应用线程(GC暂停),确保不会有线程在操作内存,同时,状态的快照是可以确定的,以便GC工作。

2. 堆栈遍历

        在执行线程转储(Thread Dump)等操作时, JVM需要安全的遍历线程栈,这时需要安全点。

3.性能损耗最小

        通过在最可能长时间运行的指令设置安全点,JVM可以减少程序暂停的频率,从而降低性能损耗。

安全点的触发条件:

1.方法调用:每次方法调用都是一个潜在的安全点

2. 循环回跳:长时间循环中间会插入安全点检查

3. 异常处理:处理异常时,也会检查是否到达安全点

http://www.dtcms.com/a/351455.html

相关文章:

  • CentOS 7 服务器初始化:从 0 到 1 的安全高效配置指南
  • 使用 flutter_tts 的配置项
  • C# 13 中的新增功能实操
  • 深入了解AWS Auto Scaling
  • OpenAI API Python实战教程:如何稳定获取结构化 JSON 输出(简易/复杂 双示例)
  • Nginx Ubuntu vs CentOS 常用命令对照表---详解笔记
  • AR技术引领航空制造迈向智能化新时代
  • Java标识符命名规则与规范
  • 32.Attention-注意力机制
  • 【算法--链表题2】19.删除链表的倒数第 N 个节点:通俗详解
  • A股大盘数据-20250826 分析
  • Java大厂面试实战:从Spring Boot到微服务架构的全链路技术剖析
  • 英伟达jetson开发板Ubuntu系统配置显示屏系统脱离手动输入指令自动编译执行操作
  • InnoDB详解2
  • 从混乱到高效:企业如何构建可持续发展的IT工单系统
  • 清分系统在电商中的一些案例
  • nginx-负载均衡
  • GeoServer与GISBox:地理数据服务器对比解析
  • 【STM32】CubeMX(十三):RT-THREAD
  • 脑电分析——学习笔记
  • 常用测试有哪些
  • Spring Boot 集成 Docker 构建与发版完整指南
  • [docker]Failed to initialize NVML: Unknown Error
  • 【C++】用哈希表封装实现unordered_set和unordered_map
  • 深入剖析悲观锁、乐观锁与分布式锁
  • 如何才能使RISC V架构成为机器学习的核心
  • U-Net图像语义分割中梯度下降的直观解释
  • 动态规划:为什么暴力算法会有重复子问题
  • 深度学习自动驾驶BEV【专业名词解释汇总】
  • VS中创建Linux项目