S++

千线一眼

导航

< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5

统计

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   S++  阅读(33)  评论(0编辑  收藏  举报

相关博文:
阅读排行:
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
点击右上角即可分享
微信分享提示