JVM将虚拟机分成了哪几块区域?

admin2024-04-03  0

Java 8之后,JVM(Java Virtual Machine)继续沿用原有的内存区域划分,主要包括以下几个部分:

1、堆(Heap)

    • 用途:存储对象实例,几乎所有通过new关键字创建的对象都会分配在堆中。
    • 特性:堆是JVM内存管理的重点区域,是所有线程共享的。它进一步划分为新生代(Young Generation)、老年代(Old Generation)和元空间(Metaspace)。

新生代

    • 包含 Eden 区、From Survivor 区和 To Survivor 区,主要用于存放新创建的对象。大部分对象在新生代中经历短暂的生命周期后被垃圾收集器回收。

老年代

    • 存储经历过多次新生代垃圾回收仍然存活的对象,或者大对象(超过一定阈值,如 -XX:PretenureSizeThreshold 设置的值)会直接进入老年代。

2、元空间

    • 在Java 8中,方法区(Method Area)的一部分——类元数据信息被移到了元空间(Metaspace)。元空间不在堆中分配,而是直接使用本地内存,用于存储类的结构信息(如类名、字段、方法、常量池等)、方法代码、运行时常量池以及类级别的静态变量等。

之前方法区(Method Area)

    • 用途:在Java 8之前,方法区是JVM规范中定义的一个概念,用于存储类的结构信息、常量池、静态变量等。Java 8之后,大部分方法区的功能被转移到了元空间(Metaspace),方法区这一术语在规范中的意义变得模糊,实际实现中方法区的概念被弱化,但某些文献或讨论中仍可能沿用这一术语来指代类的元数据存储区域。
    • 特性:方法区是各个线程共享的内存区域,其中的内存回收目标主要是针对废弃的常量和不再使用的类型数据。

3、栈(Stack)

    • 用途:每个线程都有自己独立的栈空间,用于存储方法调用时的局部变量、操作数栈、动态链接、方法出口等信息。每个方法调用对应一个栈帧(Stack Frame)。
    • 特性:栈是线程私有的,生命周期与线程相同,随着线程的创建而创建,随着线程的结束而销毁。栈的内存分配和回收都是确定的,速度快且高效。

4、程序计数器(Program Counter Register)

    • 用途:记录当前线程正在执行的字节码指令的地址(偏移量)。如果是Native方法,则记录为undefined
    • 特性:每个线程都有自己的程序计数器,是线程私有的。

5、本地方法栈(Native Method Stack)

    • 用途:与Java方法栈类似,用于支持native方法(用C/C++等非Java语言实现的方法)的调用。存储本地方法的局部变量、参数、返回值等信息。
    • 特性:每个线程都有一个本地方法栈,也是线程私有的。

综上所述,Java 8之后的JVM内存区域主要分为堆、方法区(与元空间的关系需根据上下文理解)、栈(包括Java虚拟机栈和本地方法栈)以及程序计数器。其中,堆被细分为新生代和老年代,而类的元数据信息存储在元空间中。这些区域各自承担着不同的职责,共同协作以支持Java程序的运行。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明原文出处。如若内容造成侵权/违法违规/事实不符,请联系SD编程学习网:675289112@qq.com进行投诉反馈,一经查实,立即删除!