S++

千线一眼

导航

JVM-内存结构

学习路线

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

定义

  • 一般是机器的寄存器

作用

  • 记录下一条JVM指令指定的地址

特点

  • 线程私有
  • 不会存在内存溢出

2. 虚拟机栈(JVM Stacks)

定义

  • 栈:先进后出的存储结构
  • 每个线程运行时所需要的内存空间,成为虚拟机栈

栈帧

  • 每个栈由多个栈帧(Frame)组成
  • 栈帧对应每个方法运行时需要的内存
  • 每个线程只能有一个活动栈帧,对应当前正在执行的那个方法

思考1:垃圾回收是否涉及到栈内存?

答:不涉及。在调用结束后所有栈帧都会被弹出栈(自动出栈),并不需要垃圾回收。

思考2:栈内存的分配越大越好吗?

答:物理内存的大小一定,如果栈的内存分配过大,那么运行线程的数量就会变小。

思考3:方法内的局部变量是否线程安全?

答:如果方法内局部变量是没有逃离方法的作用范围则是安全的;如果局部变量引用了对象,并逃离了方法的作用范围则是不安全的。


栈的内存溢出

原因
  • 栈帧过多
  • 栈帧过大(不常见)

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

作用

  • 为本地方法的运行提供运行空间

4. 堆(Heap)

定义

  • Java堆是被所有线程共享的一块内存区域,在虚拟机启动时创建
  • 通过new关键字创建对象都会使用堆内存

特点

  • 线程共享,堆中的对象需要考虑线程安全问题
  • 有垃圾回收机制

堆的内存溢出

  • 大量对象强引用无法回收导致溢出

特殊情况:垃圾回收后内存占用仍然很高

排查手段:堆转储


5. 方法区(Method Area)

方法区定义

定义

  • 方法区与java堆一样,是各个线程共享的内存区域
  • 方法区在jvm启动的时候被创建

方法区内存溢出

  • 1.8以前是永久代溢出
  • 1.8以后是元空间溢出

运行时常量池

  • 常量池:一张表。虚拟机指令根据这张常量表找到要执行的类名、方法名、参数类型、字面量等信息
  • 运行时常量池:常量池是*.class文件中的,当该类被加载,它的常量池信息就会被放入运行时常量池,并将里面的符号地址改为真实地址。

posted on 2022-04-25 14:00  S++  阅读(40)  评论(0)    收藏  举报