JVM中哪些是线程共享区和线程私有区

1.堆区方法区所有线程共享的。2.栈、本地方法栈、程序计数器每个线程独有

在 JVM 的内存模型中,内存区域可以分为线程共享线程私有

线程共享区是所有线程共享的内存区域

线程私有区是每个线程独立拥有的内存区域

下面我们详细分析 JVM 中的线程共享区。

1. 线程共享区的组成

JVM 中的线程共享区包括以下部分:

  1. 方法区(Method Area)

  2. 堆(Heap)


2. 方法区(Method Area)

(1)作用
  • 方法区用于存储类的元数据信息,包括:

    • 类的结构信息(如类名、方法名、字段名等)。

    • 运行时常量池(Runtime Constant Pool)。

    • 静态变量(Static Variables)。

    • 方法字节码(Method Code)。

(2)特点
  • 方法区是所有线程共享的。

  • 方法区的内存不需要连续,可以是物理上不连续的内存空间

  • 方法区的内存回收主要是针对常量池和类型的卸载

(3)实现
  • JDK 8 之前,方法区的实现是 永久代(PermGen)

  • JDK 8 及之后,方法区的实现是 元空间(Metaspace),使用本地内存(Native Memory)存储。

(4)示例
class MyClass {
    static int staticVar = 10; // 静态变量存储在方法区
    void myMethod() {
        System.out.println("Hello, World!"); // 方法字节码存储在方法区
    }
}

3. 堆(Heap)

(1)作用
  • 堆用于存储对象实例和数组。

  • 几乎所有通过 new 关键字创建的对象都分配在堆中。

(2)特点
  • 堆是所有线程共享的。

  • 堆是 JVM 中最大的一块内存区域

  • 堆的内存回收由垃圾回收器(GC)负责

(3)分区
  • 可以分为以下几个区域:

    1. 新生代(Young Generation)

      • 用于存放新创建的对象。

      • 分为 Eden 区、Survivor 区(From 和 To)。

    2. 老年代(Old Generation)

      • 用于存放长期存活的对象。

    3. 元空间(Metaspace)

      • 在 JDK 8 及之后,元空间从堆中分离出来,使用本地内存存储。

(4)示例
Object obj = new Object(); // 对象实例存储在堆中
int[] arr = new int[10];   // 数组存储在堆中

4. 线程共享区与线程私有区的对比

区域线程共享区线程私有区
方法区存储类的元数据、静态变量、常量池等。
存储对象实例和数组。
虚拟机栈存储方法的局部变量、操作数栈等。
本地方法栈存储本地方法的调用信息。
程序计数器存储当前线程执行的字节码指令地址。

5. 总结

线程共享区说明
方法区存储类的元数据、静态变量、常量池等。
存储对象实例和数组。

6. 一句话总结

JVM 中的线程共享区包括方法区和堆方法区存储类的元数据和静态变量,堆存储对象实例和数组。

线程私有区

在 JVM 的内存模型中,线程私有区是每个线程独立拥有的内存区域,用于存储线程私有的数据。线程私有区包括以下几个部分:


1. 线程私有区的组成

JVM 中的线程私有区包括以下部分:

  1. 程序计数器(Program Counter Register)

  2. 虚拟机栈(Java Virtual Machine Stack)

  3. 本地方法栈(Native Method Stack)


2. 程序计数器(Program Counter Register)

(1)作用
  • 程序计数器用于存储当前线程正在执行的字节码指令的地址。

  • 如果当前线程正在执行 Java 方法,程序计数器存储的是虚拟机字节码指令的地址。

  • 如果当前线程正在执行本地方法(Native Method),程序计数器的值为空(Undefined)。

(2)特点
  • 程序计数器是线程私有的,每个线程都有自己的程序计数器。

  • 程序计数器是 JVM 中唯一不会发生内存溢出(OutOfMemoryError)的区域。

(3)示例
public void myMethod() {
    int a = 10; // 字节码指令地址存储在程序计数器中
    int b = 20;
    int c = a + b;
}

3. 虚拟机栈(Java Virtual Machine Stack)

(1)作用
  • 虚拟机栈用于存储 Java 方法的调用信息,包括:

    • 局部变量表(Local Variable Table):存储方法的局部变量。

    • 操作数栈(Operand Stack):用于执行字节码指令时的操作数存储。

    • 动态链接(Dynamic Linking):指向运行时常量池的方法引用。

    • 方法返回地址(Return Address):存储方法执行完成后的返回地址。

(2)特点
  • 虚拟机栈是线程私有的,每个线程都有自己的虚拟机栈。

  • 虚拟机栈的内存大小可以通过 JVM 参数 -Xss 设置。

  • 如果线程请求的栈深度超过虚拟机栈的最大深度,会抛出 StackOverflowError

  • 如果虚拟机栈无法申请到足够的内存,会抛出 OutOfMemoryError

(3)示例
public void myMethod() {
    int a = 10; // 局部变量 a 存储在局部变量表中
    int b = 20;
    int c = a + b; // 操作数栈用于存储 a 和 b 的值
}

4. 本地方法栈(Native Method Stack)

(1)作用
  • 本地方法栈用于存储本地方法(Native Method)的调用信息。

  • 本地方法是用其他语言(如 C/C++)编写的方法,通过 Java Native Interface (JNI) 调用。

(2)特点
  • 本地方法栈是线程私有的,每个线程都有自己的本地方法栈。

  • 本地方法栈的内存大小可以通过 JVM 参数设置。

  • 如果线程请求的栈深度超过本地方法栈的最大深度,会抛出 StackOverflowError

  • 如果本地方法栈无法申请到足够的内存,会抛出 OutOfMemoryError

(3)示例
public native void myNativeMethod(); // 本地方法的调用信息存储在本地方法栈中

5. 线程私有区与线程共享区的对比

区域线程私有区线程共享区
程序计数器存储当前线程执行的字节码指令地址。
虚拟机栈存储 Java 方法的调用信息。
本地方法栈存储本地方法的调用信息。
方法区存储类的元数据、静态变量、常量池等。
存储对象实例和数组。

6. 总结

线程私有区说明
程序计数器存储当前线程执行的字节码指令地址。
虚拟机栈存储 Java 方法的调用信息,包括局部变量表、操作数栈等。
本地方法栈存储本地方法的调用信息。

7. 一句话总结

JVM 中的线程私有区包括程序计数器、虚拟机栈和本地方法栈,用于存储线程私有的数据和方法调用信息。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

EthanMilk

你的鼓励是我创作的最大动力谢谢

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值