java虚拟机2

一、垃圾回收机制(GC)

  1. 回收区域:GC主要回收堆内存区域。堆用于存放new出来的对象 。程序计数器、元数据区和栈一般不是GC回收的重点区域。

  2. 回收单位:GC以对象为单位回收内存,而非字节。按对象维度回收更简便,若按字节维度则需详细描述对象各部分是否回收,较为复杂。

  3. 对象存活判定 - 可达性分析:Java通过可达性分析判定对象是否可被回收。从GC roots(如栈上的局部变量、常量池里指向的对象、元数据区的静态成员等)开始扫描,能被访问到的对象标记为可达,不可达的对象则可被回收。如在构建二叉树的代码示例中,通过改变引用关系可使某些对象变得不可达从而可被回收 。

  4. 回收算法

  • 标记 - 清除:先标记可回收对象,再直接释放其内存。优点是简单直接,缺点是会产生内存碎片。

  • 复制:将存活对象复制到另一块空间,然后释放原空间。可解决内存碎片问题,但存在内存浪费,且复制开销大,尤其在存活对象多的情况下。

  • 标记 - 整理:先标记可回收对象,然后将存活对象向一端移动,再释放边界外的内存。能解决内存碎片问题,也避免复制算法的内存浪费,但搬运对象成本较高。

  • 分代回收:将堆空间分为新生代和老年代。新生代对象生命周期短,多采用复制算法,新创建对象放伊甸区,经过GC存活的对象进入幸存区,多次GC后仍存活的对象进入老年代。老年代对象生命周期长,采用标记 - 清除或标记 - 整理算法 。涉及minor GC(新生代高频回收)、major GC(老年代低频回收)和Full GC(整堆回收) 。

二、类加载机制

  1. 类加载流程
  • 加载:找到并读取.class文件内容到内存,构建类对象。

  • 验证:校验读取内容的合法性。

  • 准备:为类对象分配未初始化的内存空间,静态成员赋默认值。

  • 解析:初始化常量并加载到内存。

  • 初始化:执行类的静态代码块,对静态成员真正初始化 。

  1. 触发类加载时机:懒汉模式下,类在第一次被使用时触发加载,如构造实例、调用静态方法、使用静态成员等情况 。

  2. 双亲委派模型

  • 类加载器:JVM自带Bootstrap ClassLoader(负责标准库查找)、Extension ClassLoader(负责扩展库查找)、Application ClassLoader(负责第三方库和当前项目查找) 。

  • 模型过程:类加载时,先由子类加载器将请求委派给父类加载器,父类加载器依次向上查找,直至Bootstrap ClassLoader。若父类加载器未找到类,才由子类加载器尝试加载。如加载java.lang.String类由Bootstrap ClassLoader负责,加载自定义的com.bit.Test类则按层级查找 。该模型确保标准库优先加载,也可被打破,程序员可自定义类加载器 。

三、相关对比与补充

  • 与C/C++内存管理对比:C/C++申请内存需手动释放,易因遗忘释放导致内存泄露。Java等语言引入GC自动管理内存,提高开发效率。C/C++未引入GC是因设计理念注重与C兼容及极致性能,引入GC会增加运行时开销影响性能 。

  • GC对执行效率影响:触发GC时可能出现stop the world(STW)问题,即暂停其他工作线程,影响程序执行效率 。

四、以下是从图片中提取的部分关键代码示例:

// 二叉树构建示例

class Node {

Node left;

Node right;

}

Node build() {

Node a = new Node();

Node b = new Node();

Node c = new Node();

Node d = new Node();

Node e = new Node();

Node f = new Node();

Node g = new Node();

a.left = b;

a.right = c;

b.left = d;

b.right = e;

e.left = g;

c.right = f;

return a;

}

Node root = build();

// 后续可通过改变引用关系使某些对象不可达,如:

// root.right.right = null; 使f不可达

// root.right = null; 使c和f不可达

// 类加载时机相关示例

class Test {

static int n = 10;

// 当使用Test类的静态成员n,或构造Test实例,或调用Test的静态方法时,会触发类加载

}

相关推荐
七七&5561 分钟前
Spring Boot 常用注解整理
java·spring boot·后端
爱吃煎蛋的小新5 分钟前
WPF入门 #1 WPF布局基础
笔记·学习·c#·wpf
北京_宏哥6 分钟前
🔥《刚刚问世》系列初窥篇-Java+Playwright自动化测试-21- 操作鼠标拖拽 - 中篇(详细教程)
java·前端·面试
qqxhb7 分钟前
零基础设计模式——总结与进阶 - 3. 学习资源与下一步
学习·设计模式·重构·代码整洁之道
程序员小假9 分钟前
说一说 @Autowired 注解实现原理
java·后端
我叫小白菜10 分钟前
【Java_EE】设计模式
java·开发语言·设计模式
✎ ﹏梦醒͜ღ҉繁华落℘10 分钟前
WPF学习(二)
学习·wpf
程序员岳焱12 分钟前
SpringMVC 开发避坑指南:十大常见问题深度解析与解决方案
java·后端·spring
心月狐的流火号12 分钟前
Java 类加载机制深度解析
jvm
不学无术の码农14 分钟前
《Effective Python》第九章 并发与并行——使用 Queue 实现并发重构
开发语言·python