YWW
YWW
发布于 2025-08-20 / 4 阅读
0
0

JVM内存原理理解

1.JVM是啥a?

JVM是java虚拟机,可以在任何拥有jvm的平台运行java的字节码文件【.class文件】,JVM实现了java跨平台特性。

我们编写的Java源代码首先需要通过Java编译器生成字节码文件,然后由JVM负责解释执行这些字节码。

2.重点理解:JVM内存机制

  1. JVM的内存组成 ?

(1)堆:一块内存,被所有线程共享。存放【生成的对象】

所以为什么会有堆内存占满的问题出现,和对象内存回收有很大关联

(2)栈:虚拟机栈和本地方法栈

虚拟机栈:线程私有,存放【基本类型变量+对象引用变量

包装类型(Integer,Character)都是普通对象,放堆内存

创建完对象,这个对象名作为变量存在这里 栈中数据是共享的

本地方法栈:为虚拟机中使用的Native方法服务

  • 虚拟机栈为虚拟机执行Java方法(字节码)服务

  • 栈的深度如果超过虚拟机允许的深度,抛出StackOverflowError异常

  • 扩展虚拟机栈时,扩展无法申请到足够的内存 抛出OutOfMemoryError
    【这里OOM依旧和内存是否充足有关】

(3)方法区:存放.class字节码文件,包含所有虚拟机加载的类、常量、静态变量等,存的都是整个程序中唯一的元素(static变量、class)

(4)程序计数器:线程私有的,理解为:维护当前这个线程执行的字节码的行号


2. JVM内存模型


jdk1.8之后JVM内存模型将永久代替换--元空间,常量池依旧在方法区

垃圾回收机制是这样的:

(1) 新产生的对象放在Eden区里

(2) eden区满了,存活的对象复制到from区中

【如果存活对象from放不下,这些存活对象全部进入老年代,之后的eden区内存回收掉】

(3) 继续分配到eden,eden再次满了 eden+from 存活对象复制到to区

【to满则进入老年代,eden/from 内存都回收】

(4) 默认情况,一个对象复制15次,就进入老年代

(5) 老年代满了或放不下,进行一次full GC

垃圾回收

1.Minor GC

新生代回收:不影响老年代,需要速度快:复制算法

2.Full GC

老年代回收:整个堆的内存回收,标记-清除,标记-压缩

垃圾回收算法常见的几种:

(1) 复制算法:

从根集合节点扫描,标记所有存活对象,将这些存活对象复制到一块新的内存,然后把原来的内存回收

eden:from: to 一般是8:1:1,eden满了则把对象复制到from ,然后回收eden内存,eden/from 满了则复制到to,然后回收eden/from

(2) 标记-清理 算法:

先从根节点开始 标记所有对象,没标记的就是未被引用的对象,清除阶段,清除所有的未标记对象
【适合清除老年代,但容易产生内存碎片,扫描空间两次(标记/清除)】

(3) 标记-压缩 算法:

先从根节点做一次标记,然后把存活对象压缩到内存的一段,
清除阶段:清理边界外的所有空间,减少了碎片内存产生

(4) 分代收集算法:

不同代用不同的算法,新生代-复制算法;老年代-标记压缩


评论