Jvm核心:栈、HotSpot 和 堆

一、栈(Stack)🛠️📦

在 JVM 中主要用于管理方法的调用和局部变量。每当一个方法被调用时,JVM 就会为这个方法分配一个栈帧(Stack Frame),栈帧会存放局部变量、操作数栈以及方法的返回地址。当方法调用结束,栈帧就会被释放。

栈的特点 📌:
  1. LIFO(后进先出):栈是“后进先出”的数据结构。就像叠放盘子🍽️,最后放上去的盘子最先被拿走。方法也是这样,最后调用的方法最先结束并被移出栈。
  2. 线程私有:栈是每个线程独享的。每个线程在执行时都有自己的栈,这就是为什么 Java 中局部变量是线程安全的,因为它们存在于各自线程的栈中。
栈的组成部分 🛠️:
  1. 局部变量表:用于存放方法的局部变量,比如函数参数和函数内定义的变量📝。
  2. 操作数栈:用于执行操作时保存中间结果,就像做算术时用的草稿纸✏️。
  3. 帧数据:包含方法的返回值、返回地址等信息📍,用于帮助程序知道执行完这个方法后应该回到哪里。
现实类比 🍰:

想象你在厨房做蛋糕🍰。你有一个蛋糕食谱(方法),每次你执行一个步骤时,就会记录你用的原材料(局部变量)。当你完成这一步时,你会“把盘子从堆栈中拿走”并继续下一步。栈就是这样管理方法的每个步骤和它的局部数据。

栈溢出(StackOverflow)💥:

如果递归调用太多而没有终止条件,栈帧会不断堆叠,最终导致栈溢出(StackOverflowError)。这就像在厨房里放太多盘子,一旦超过了厨房的容量,盘子就会掉下来,程序崩溃了!

public class StackOverflowExample {
    public static void recursiveMethod() {
        recursiveMethod();  // 递归调用,没有终止条件,会导致栈溢出
    }

    public static void main(String[] args) {
        recursiveMethod();  // 程序将崩溃并抛出StackOverflowError
    }
}


二、HotSpot JVM 🧠🔥

HotSpot 是最常用的 JVM 实现,它是 Sun Microsystems 开发并且现在由 Oracle 维护的 JVM。HotSpot 之所以叫这个名字,是因为它采用了一种叫做 热点探测(HotSpot Detection) 的技术,能够动态优化那些被频繁调用的方法,从而提高程序的性能。

HotSpot 的两个核心功能 ✨:
  1. 即时编译(Just-In-Time Compilation, JIT):JIT 编译器会将热点代码(被频繁执行的代码)从字节码编译成机器码,从而加快执行速度。这就像你发现某个蛋糕配方特别好用🍰,你就会提前把它打印出来,后面直接使用,无需每次都查阅📜。
  2. 垃圾回收(Garbage Collection, GC):HotSpot 的 GC 机制非常高效,它自动回收不再使用的对象占用的内存,确保内存不被浪费,防止内存泄漏。
HotSpot 的执行流程 🛤️:
  • 解释器(Interpreter):当 Java 程序第一次执行时,HotSpot 会用解释器逐行解释执行代码,但这个速度会比较慢。
  • JIT 编译器:当 HotSpot 发现某些方法被频繁调用时,它会将这些方法编译为机器码,后续直接执行机器码,大大加快执行速度。
现实类比 🔥:

想象你在厨房做饭,刚开始你按照一本食谱慢慢来做(解释执行),但如果你每天都做同一道菜,你就会记住步骤,甚至提前准备好调料,后面可以直接快速完成(JIT 编译)。HotSpot 就是通过这种方式提升性能的。


三、堆(Heap)📦🌳

是 JVM 的主要内存区域,用于存放所有的对象和数组。堆是 JVM 中最大的一块内存区域,几乎所有对象的创建和分配都发生在堆中。

堆的特点 📌:
  1. 线程共享:堆是所有线程共享的,因此在多线程环境中,多个线程可以同时访问堆中的对象。
  2. 垃圾回收:堆中的内存是由 垃圾回收器(Garbage Collector) 管理的,GC 负责自动回收那些不再被引用的对象,释放内存。
堆的划分 🧩:

堆通常被分为两个主要区域:

  1. 新生代(Young Generation):存放新创建的对象。大多数对象在新生代中只存活很短的时间。
    • Eden 区:所有新对象首先分配到 Eden 区,就像植物的“伊甸园”🌱,新对象一开始都在这里“生长”。
    • Survivor 区:当对象在 Eden 区“存活”足够久后,会移动到 Survivor 区。
  2. 老年代(Old Generation):存放生命周期较长的对象。如果一个对象在新生代中经过多次 GC 后仍然存活,它就会被移动到老年代。
垃圾回收(GC)🚮:

垃圾回收是堆管理的重要部分,它通过自动回收不再使用的对象,防止内存泄漏。HotSpot 中有多种垃圾回收算法,比如 串行 GC并行 GCG1 GC,每种算法都适用于不同的应用场景。

现实类比 🏠:

你可以把 想象成你的家📦,每个新买回来的家具(对象)都先放在客厅(新生代)。如果某些家具(对象)一直没被使用,垃圾回收器就会把它们丢掉。如果有些家具你用了很久,它们会被移到储藏室(老年代)长期保存。

示例代码 📝

在代码中,我们通常不会直接操作堆,但对象的分配和垃圾回收都是在堆中进行的:

public class HeapExample {
    public static void main(String[] args) {
        // 创建一个新对象,分配在堆中
        HeapExample obj = new HeapExample();
        
        // 调用垃圾回收
        System.gc();
        
        System.out.println("对象在堆中被创建和垃圾回收处理");
    }

    @Override
    protected void finalize() throws Throwable {
        System.out.println("对象正在被垃圾回收器回收");
    }
}

在这个例子中,当我们调用 System.gc() 时,JVM 会尝试触发垃圾回收,清除不再使用的对象。finalize() 方法会在对象被回收前调用,我们可以用它来观察垃圾回收的发生。


总结 🌟:

  1. 栈(Stack):用于管理方法调用和局部变量。每个线程都有自己的栈,栈是后进先出的结构。
  2. HotSpot JVM:最常用的 JVM,它通过热点探测和即时编译(JIT)来优化程序性能,具备强大的垃圾回收机制。
  3. 堆(Heap):用于存储所有的对象和数组,堆是由垃圾回收器自动管理的,分为新生代和老年代。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值