说一下JVM中,哪些是共享区,哪些可以作为gc root

124 阅读3分钟

共享区

在JVM中,共享区主要是指那些可以被多个线程共同访问的内存区域。主要包括:

  1. 方法区(Method Area)

    • 用来存储加载的类信息、常量、静态变量、编译后的代码等数据。
    • 在HotSpot虚拟机中,JDK 8及之前版本使用永久代(PermGen space)实现方法区,JDK 8及之后版本使用元空间(Metaspace)来实现。
    • 方法区是线程共享的,随着JVM的启动而创建,随着JVM的关闭而销毁。
  2. 堆内存(Heap)

    • JVM启动时创建,用于存放对象的实例。
    • 堆内存也是线程共享的,垃圾回收器主要管理堆内存。
    • 堆内存可以细分为老年代(Old Generation)和新生代(Young Generation),新生代又可以进一步细分为Eden区、From Survivor区和To Survivor区。

GC Root

GC Root是垃圾回收器进行垃圾收集时,需要判断哪些对象还“存活”的起点。

如果一个对象到GC Root没有任何引用链,那么该对象就可以被垃圾回收器回收。

GC Root主要包括以下几种:

  1. 虚拟机栈(Java Stack)中引用的对象

    • 栈帧中的局部变量表引用的对象。
    • 示例代码:
      public class Test {
          public static void main(String[] args) {
              Test a = new Test(); // a 是局部变量,此时a是GC Root
              a = null; // a与原来指向的对象断开连接,对象等待GC回收
          }
      }
      
  2. 方法区中的类静态属性引用的对象

    • 类的静态属性引用的对象。
    • 示例代码:
      public class Test {
          public static Test s = new Test(); // s是类静态属性,此时s是GC Root
      }
      
  3. 方法区中常量引用的对象

    • 常量引用的对象。
    • 示例代码:
      public class Test {
          public static final Test CONSTANT = new Test(); // CONSTANT是常量,此时CONSTANT是GC Root
      }
      
  4. 本地方法栈(Native Method Stack)中JNI(Native方法)引用的对象

    • 通过JNI调用的本地方法引用的对象。
    • 示例代码(JNI调用部分通常用C或C++编写,这里仅展示Java调用本地方法的声明):
      public class Test {
          // 声明本地方法
          public native void nativeMethod();
          
          // 在某个地方调用nativeMethod
          public static void main(String[] args) {
              Test test = new Test();
              test.nativeMethod(); // 假设nativeMethod内部引用了某些对象,这些对象在nativeMethod执行期间是GC Root
          }
      }
      

小结

类型描述示例代码片段
共享区方法区存储类信息、常量、静态变量等-
堆内存存放对象实例,垃圾回收器主要管理区域-
GC Root虚拟机栈中引用的对象Test a = new Test();
方法区中类静态属性引用的对象public static Test s = new Test();
方法区中常量引用的对象public static final Test CONSTANT = new Test();
本地方法栈中JNI引用的对象public native void nativeMethod();(本地方法内部引用)

注意:由于本地方法栈中的JNI引用通常涉及到本地代码(如C或C++),因此在Java代码中直接展示其作为GC Root的示例可能不够直观。

在实际应用中,当Java通过JNI调用本地方法时,如果本地方法内部引用了Java对象,那么这些对象在本地方法执行期间就可以被视为GC Root。

欢迎访问我的(夏壹分享)公众号 和 博客(sanzhishu)后缀top