0%

JVM(Java 虚拟机)全面解析:从原理到结构

JVM(Java Virtual Machine,Java 虚拟机)是 Java 生态的核心,它不仅是 Java 语言的运行环境,还支持 Scala、Kotlin、Groovy 等多种基于 JVM 的语言,被誉为 “最好的虚拟机”。其设计理念实现了 “一次编译,到处运行” 的跨平台特性,同时提供自动内存管理和垃圾回收等核心功能,极大简化了开发者的工作。

JVM 的核心定位与特性

作为多语言运行平台

JVM 的本质是二进制字节码的运行环境,它不直接依赖于 Java 语言,而是依赖于符合 JVM 规范的字节码(.class 文件)。任何能编译为 JVM 字节码的语言(如 Scala、Kotlin)都能在 JVM 上运行,这使得 JVM 成为跨语言的统一执行平台。

核心特性

  • 一次编译,到处运行
    Java 源码经编译生成字节码(.class),JVM 负责将字节码解释 / 编译为对应平台的机器指令,实现跨操作系统(Windows、Linux、macOS 等)和硬件架构的运行。
  • 自动内存管理
    开发者无需手动分配和释放内存,JVM 通过内存模型(如堆、栈的划分)自动管理内存分配,减少内存泄漏风险。
  • 自动垃圾回收(GC)
    JVM 内置垃圾回收器,自动识别并回收不再使用的对象内存,避免内存溢出(OOM)问题(需合理配置 GC 策略)。

编译器与解释器:JVM 的执行方式

JVM 的执行效率与其采用的 “解释 + 编译” 混合模式密切相关。理解编译器与解释器的区别,是掌握 JVM 执行原理的基础。

阅读全文 »

Spring Bean 作用域(Scope)全解析:从单例到 Web 专用作用域

Spring Bean 的作用域(Scope) 定义了 Bean 在 Spring 容器中的生命周期范围与实例创建规则,直接影响 Bean 的复用性、线程安全性和资源占用。Spring 提供 5 种核心作用域,涵盖普通 Java 应用(单例 / 原型)和 Web 应用(请求 / 会话 / 应用级),本文将详细拆解每种作用域的特性、适用场景、底层实现及注意事项。

Spring Bean 作用域总览

Spring 容器中 Bean 的 5 种作用域,按适用场景可分为普通应用作用域(适用于所有环境)和Web 专用作用域(仅适用于 Spring Web 环境,如 Spring MVC):

作用域名称 英文标识 核心特性 适用场景 生效环境
单例 singleton 容器中仅存在1 个实例,随容器启动创建(默认懒加载可配置),全局共享 无状态组件(如 Service、Dao、工具类) 所有环境(默认)
原型 prototype 每次调用 getBean() 或注入时创建新实例,容器不管理销毁 有状态组件(如 Command 对象、请求参数封装类) 所有环境
请求 request 每个 HTTP 请求对应1 个实例,请求结束后销毁 存储请求级数据(如当前请求的用户信息) Web 环境(Spring Web)
会话 session 每个 HTTP Session 对应1 个实例,会话过期后销毁 存储会话级数据(如用户登录状态、购物车) Web 环境(Spring Web)
应用 / 全局会话 application 整个 ServletContext 对应1 个实例,与应用生命周期一致 存储应用级全局数据(如系统配置、字典缓存) Web 环境(Spring Web)
阅读全文 »

Linux 中的 dentry 对象:目录项缓存与文件路径解析

在 Linux 虚拟文件系统(VFS)中,dentry(目录项)是连接文件名与 inode 的关键内存对象,负责高效解析文件路径并缓存目录结构信息。它与 inode 共同构成了文件系统的逻辑视图,理解 dentry 的工作机制有助于深入掌握 Linux 文件查找的底层流程。

dentry 的本质与核心作用

什么是 dentry?

dentry 是 “directory entry” 的缩写,即目录项,是 VFS 为解析文件路径而在内存中创建的临时数据结构。它不对应磁盘上的实际数据(与 inode 不同),而是动态生成并缓存,用于加速文件路径的查找。

核心功能

  • 建立文件名与 inode 的映射关系(通过 d_inode 指针关联 inode);
  • 组织成目录树结构,反映文件系统的层级关系(如 /home/user/file.txt 由多个 dentry 节点串联而成);
  • 缓存常用路径信息,避免重复解析磁盘目录,提升文件访问效率。

dentry 与 inode 的关系

dentry 与 inode 是 VFS 中的一对核心组合,二者的关系可概括为:

  • inode:对应磁盘上的文件元数据(权限、大小、数据块指针等),是文件的 “物理标识”;
  • dentry:对应文件的 “逻辑名称”(文件名或目录名),是 inode 在内存中的 “逻辑映射”。

关联方式

  • 每个有效 dentry 都通过 d_inode 指针指向一个 inode(一个文件 / 目录必须有 inode);
  • 一个 inode 可被多个 dentry 指向(如硬链接场景,多个文件名对应同一 inode);
  • inode 中通过 i_dentry 队列记录所有指向它的 dentry,形成 “一对多” 的反向关联。

dentry 与文件路径的解析

文件路径(如 /usr/local/bin)的解析依赖 dentry 形成的层级结构:

阅读全文 »

Spring ProxyFactoryBean 深度解析:AOP 代理的底层实现核心

ProxyFactoryBean 是 Spring AOP 与 IOC 容器融合的关键组件,它实现了 FactoryBean 接口,专门用于在 IOC 环境中创建 AOP 代理对象。不同于 @AspectJ 等高层注解驱动的 AOP 方式,ProxyFactoryBean 是更底层的实现,直接暴露了 AOP 代理的配置细节(如通知器链、代理类型选择)。从 “核心定位→源码流程→代理生成逻辑→JDK/CGLIB 对比” 四个维度,彻底讲透 ProxyFactoryBean 如何完成 AOP 代理的创建。

ProxyFactoryBean 的核心定位

在 Spring AOP 体系中,ProxyFactoryBean 的角色是 “IOC 容器中的 AOP 代理工厂”,其核心职责是:

  1. 整合 AOP 配置:管理通知(Advice)、切入点(Pointcut)、目标对象(Target)等 AOP 核心元素;
  2. 构建通知器链:将配置的拦截器 / 通知组装成 Advisor 链(AOP 拦截逻辑的执行顺序由链决定);
  3. 生成代理对象:根据目标对象类型(接口 / 类)自动选择 JDK 动态代理或 CGLIB 代理,最终通过 getObject() 方法向容器暴露代理对象。

关键继承与实现关系

ProxyFactoryBean 继承了 AdvisedSupport(封装 AOP 配置的核心类),实现了 FactoryBean<Object>(IOC 容器的工厂 Bean 接口),其类结构如下:

1
2
3
ProxyFactoryBean 
├─ 继承:AdvisedSupport(管理 Advisor、TargetSource、代理配置)
└─ 实现:FactoryBean<Object>(通过 getObject() 生成代理对象)
  • AdvisedSupport:存储 AOP 代理的所有配置(目标对象、通知器链、代理类型等),是 AOP 代理生成的 “数据源”;
  • FactoryBean:让 ProxyFactoryBean 成为 IOC 中的 “工厂 Bean”—— 容器获取的不是 ProxyFactoryBean 本身,而是其 getObject() 方法返回的AOP 代理对象

ProxyFactoryBean 核心流程:从配置到代理生成

Aop生成过程

ProxyFactoryBean 的核心入口是 getObject() 方法(实现自 FactoryBean),整个流程可分为 “初始化通知器链→生成代理实例→选择代理类型→创建具体代理” 四步。

入口方法:getObject()—— 触发代理创建

getObject() 是 ProxyFactoryBean 的核心方法,负责判断代理的作用域(单例 / 原型),并调用对应的逻辑生成代理对象:

阅读全文 »

Linux 中的 inode:文件系统的核心索引机制

在 Linux 系统中,inode(索引节点)是文件系统的基石,负责记录文件的元数据并关联实际数据块。理解 inode 的工作原理,能帮助你深入掌握文件存储、权限管理及磁盘空间分配的底层逻辑。

inode 的本质与作用

什么是 inode?

inode 是一种数据结构(可理解为 “文件属性记录表”),每一个文件或目录在创建时都会被分配一个唯一的 inode,包含以下核心信息:

  • 文件元数据:
    • 文件类型(普通文件、目录、链接等);
    • 权限(所有者、所属组、其他人的读 / 写 / 执行权限);
    • 所有者 UID 和所属组 GID;
    • 文件大小、创建时间(ctime)、修改时间(mtime)、访问时间(atime);
    • 链接数(硬链接数量)。
  • 数据块指针:记录文件内容实际存储在磁盘的哪些 Block(数据块)中。

关键点:inode 不包含文件名,文件名与 inode 的映射关系由目录的 inode 维护。

inode 与 Block 的关系

  • inode:相当于文件的 “身份证” 和 “地址簿”,记录属性并指向数据存储位置。
  • Block:磁盘中实际存储文件内容的空间(如文本、图片数据),大小固定(常见 4KB)。

当访问文件时,系统流程为:

  1. 通过文件名在目录的 inode 中找到对应的 inode 号;
  2. 用 inode 号找到文件的 inode 结构;
  3. 根据 inode 中的 Block 指针读取实际数据。

inode 的关键特性

唯一性与固定数量

  • 每个文件系统(如 /dev/sda1)在格式化时会预分配固定数量的 inode,与 Block 分开存储(通常占磁盘空间的 1% 左右)。
  • 同一文件系统中,inode 号唯一;不同文件系统中,inode 号可重复(但无冲突,因属于不同分区)。
阅读全文 »