JVM内存

运行时数据区

运行时数据区又分为:方法区、堆、虚拟机栈、本地方法栈、程序计数器

线程私有的有:程序计数器、虚拟机栈、本地方法栈

线程共享的有:堆、方法区

堆内存

分为 新生代(Young Generation)、老年代(Old Generation)、永久代(Permanent Generation,已废弃), 三者共同构成 JVM 堆的核心存储区域,主要用于存放 Java 对象实例。

  1. 新生代
  • 新生代是 对象刚被创建时分配内存的区域,主要存放 生命周期较短的对象(比如方法局部变量、临时创建的对象)。
  • 新生代进一步分为三个部分:
    • Eden 区(伊甸园):
      对象最初创建时都放在这里,空间较大(占新生代的 80% 左右)。当 Eden 区满时,会触发 Minor GC,存活的对象会被复制到 Survivor 区。
    • Survivor 区(幸存者区):
      分为 From Survivor 和 To Survivor 两个区域(各占新生代的 10% 左右)。
      每次 Minor GC 后,Eden 区和 From Survivor 区中存活的对象会被复制到 To Survivor 区,然后清空 Eden 和 From Survivor。
      经过多次 GC 仍然存活的对象(默认 15 次),会被晋升到 老年代。
  1. 老年代
  • 老年代用于存放 生命周期较长的对象(比如缓存数据、单例对象)。
    这些对象通常是从新生代晋升而来,经过多次 Minor GC 后仍然存活。
  • 垃圾回收
    老年代的 GC 称为 Major GC(或 Full GC),执行频率较低,但耗时较长。
    当老年代空间不足时,会触发 Full GC,回收整个堆内存(包括新生代和老年代)。
    Full GC 会导致应用程序停顿(Stop-The-World),因此需要尽量减少其发生频率。
  1. 永久代(Permanent Generation,已废弃)
  • 作用(JDK 1.7 及之前)
    永久代用于存放 类的元数据(比如类的结构信息、方法、字段)、常量池、静态变量 等。
    它与堆的其他区域不同,不存放对象实例,而是存放类相关的信息。
  • 为什么废弃?
    永久代的大小难以预测:类的数量可能很多,容易导致内存溢出(OutOfMemoryError: PermGen space)。
    JDK 1.8 及之后,永久代被 元空间(Metaspace) 取代,元空间使用 本地内存,不再占用堆内存,从而避免了 PermGen 溢出问题。

程序计数器:

记录当前线程正在执行的字节码指令的地址,物理上程序计数器是使用"寄存器"完成的。

虚拟机栈:

● 也叫线程栈,每个线程运行时所需要的内存,一个栈是由多个栈帧组成

● 栈帧对应着每次方法调用时所占有的内存,存储的内容是:方法参数、方法内局部变量、方法返回地址

● 一个线程每时刻只能有一个活动栈帧,对应当前正在执行的方法

● 垃圾回收不涉及到 栈内存

● 方法递归过多 会导致 java.lang.StackOverflowError 栈内存溢出

本地方法栈

● 本地方法接口运行时所需要的内存空间

● 以 native 修饰的方法就是本地方法,本地方法不是用Java写的(没有方法实现的,只有一个接口供Java调用),而是用C或C++编写,因为 Java 有些时候不能直接和操作系统底层打交道,因此Java通过接口间接调用C或C++编写的本地方法来与操作系统底层的API打交道。即Java通过本地方法调用操作系统底层功能。

方法区

● 线程共享的区域,存储的是类信息、静态变量、常量、编译后的代码、运行时常量池

● JDK7方法区的实现叫:永久代,占用的是堆的内存空间,大小固定

● JDK8方法区的实现叫:元空间,占用的是本地内存的空间,大小自动调整

TLAB

定义:TLAB 是 JVM 的一种内存分配的优化机制。用于提高多线程环境下,内存分配的效率。

问题引入:多线程同时new对象时,JVM为其分配内存,为了防止内存重复分配,需要加入互斥锁,降低了内存分配的速度。

解决方案:所以引入了TLAB的概念,Threal Local Allocate Buffer,是每个线程在Eden区专属的一块区域,当线程的TLAB区域未满时,可以直接在其中分配内存,不需要加锁,提高内存分配速度。

当一个线程创建的时候,JVM会为这个线程分配一个固定大小的TLAB空间

TLAB 仅优化内存分配:TLAB 的线程安全仅体现在内存分配过程中,与对象本身的线程安全性无关

相关推荐
Derek_Smart1 天前
从一次 OOM 事故说起:打造生产级的 JVM 健康检查组件
java·jvm·spring boot
大道至简Edward2 天前
深入 JVM 核心:一文读懂 Class 文件结构(附 Hex 实战解析)
jvm
weisian1515 天前
JVM--20-面试题6:如何判断对象可以被垃圾回收?
jvm·可达性算法
蚊子码农5 天前
每日一题--JVM线程分析与死锁排查
jvm
xuxie996 天前
NEXT 1 进程2
java·开发语言·jvm
weisian1516 天前
JVM--19-面试题5:说说JVM的类加载机制和双亲委派模型
jvm·双亲委派模型·jvm类加载机制
亓才孓6 天前
【反射机制】
java·javascript·jvm
Volunteer Technology6 天前
JVM之性能优化
jvm·python·性能优化
Andy Dennis6 天前
Java语法注意事项
java·开发语言·jvm
坚持的小马6 天前
JVM相关笔记-jps
jvm·笔记