JVM组成及运行流程 - 面试笔记

JVM整体架构

JVM(Java Virtual Machine)是Java程序运行的核心环境,主要由以下几个部分组成:
JVM组成、运行流程

1. 程序计数器(Program Counter)

  • 特点:线程私有,每个线程都有独立的程序计数器
  • 作用:记录当前线程正在执行的字节码指令地址(行号)
  • 重要性:支持线程切换和恢复,确保程序能够正确执行

2. 虚拟机栈(JVM Stack)

  • 特点:线程私有,采用先进后出(LIFO)的数据结构
  • 组成:由多个栈帧组成,每个方法调用创建一个栈帧
  • 栈帧内容:局部变量表、操作数栈、动态链接、方法返回地址
虚拟机栈常见问题

垃圾回收是否涉及栈内存?
不涉及。垃圾回收主要针对堆内存,栈帧在方法执行完毕后自动弹出释放内存。

栈内存分配越大越好吗?
不是。默认栈内存通常为1024KB,过大会导致可创建的线程数减少。例如:512MB总内存,1024KB栈大小可创建512个线程,改为2048KB则只能创建256个线程。

方法内的局部变量是否线程安全?

  • 如果局部变量没有逃离方法作用范围,则线程安全
  • 如果局部变量引用了对象并逃离方法作用范围,需要考虑线程安全问题
栈内存溢出情况
  • 栈帧过多导致溢出(典型:无限递归调用)
  • 单个栈帧过大导致溢出

3. 堆内存(Heap)

  • 特点:线程共享区域,JVM中最大的内存区域
  • 作用:存储对象实例和数组
  • 异常:当堆内存不足时抛出OutOfMemoryError异常
  • 分代结构:通常分为年轻代(Eden、Survivor)和老年代

4. 方法区(Method Area)

  • 特点:线程共享的内存区域
  • 存储内容:类信息、运行时常量池、静态变量、编译后的代码
  • 生命周期:虚拟机启动时创建,关闭时释放
  • 异常:内存不足时抛出OutOfMemoryError: Metaspace
JDK版本差异

JDK 1.7 vs 1.8的重要变化:

  • JDK 1.7:存在永久代(PermGen),存储类信息、静态变量、常量等
  • JDK 1.8:移除永久代,改为元空间(Metaspace),使用本地内存,有效防止内存溢出
    JDK版本区别

5. 直接内存(Direct Memory)

  • 特点:不属于JVM内存结构,不由JVM管理
  • 本质:使用系统内存,常见于NIO操作
  • 特性:分配回收成本较高,但读写性能优秀
  • 用途:主要用作数据缓冲区
    直接内存

内存管理要点

垃圾回收机制

  • 主要针对堆内存进行回收
  • 栈内存随方法调用结束自动释放
  • 方法区在JDK 1.8后使用元空间,减少OOM风险

线程安全考虑

  • 程序计数器、虚拟机栈:线程私有,天然线程安全
  • 堆内存、方法区:线程共享,需要考虑并发访问问题
  • 直接内存:需要程序员手动管理,注意内存泄漏

面试重点

  1. 内存区域划分:能清楚说明各个内存区域的作用和特点
  2. 线程安全性:理解哪些区域是线程私有的,哪些是共享的
  3. 内存溢出:了解各种OutOfMemoryError的产生原因和解决方案
  4. JDK版本差异:特别是永久代到元空间的变化
  5. 性能调优:理解不同内存区域对性能的影响

补充知识点

常见JVM参数

  • -Xms:初始堆大小
  • -Xmx:最大堆大小
  • -Xss:栈大小
  • -XX:MetaspaceSize:元空间初始大小
  • -XX:MaxMetaspaceSize:元空间最大大小

内存泄漏常见场景

  • 长生命周期对象持有短生命周期对象的引用
  • 静态集合类引用大量对象
  • 监听器和回调函数未正确移除
  • 线程池中的线程未正确关闭
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值