java通关整理-JVM内存管理

网上收集整理,仅供笔记参考学习

1.JVM内存管理

在这里插入图片描述
JVM体系结构:

  • 类装载器ClassLoader:用来装载.class文件
  • 执行引擎:执行字节码,或者执行本地方法
  • 运行时数据区:方法区、堆、Java栈、程序计数器、本地方法栈

各个部分存储的内容:
在这里插入图片描述

1.1 (Java 虚拟机)栈

每个方法在执行时都会床创建一个栈帧,其中最中要的四部分是局部变量表、操作数栈、动态链接、方法出口
一个方法从调用到执行结束,就对应一个栈帧中入栈出栈的过程。
局部变量表:存放变量的值
操作数栈:执行数据计算操作
动态链表:每个栈帧都包含一个指向运行时常量池中该栈帧所属方法的引用,持有这个引用是为了支持方法调用过程中的动态链接。
方法出口:方法执行完毕

1.1.1 栈内部结构

一个方法对应一个栈帧
一个线程/一个主函数中有多个方法
程序计数器:记录程序运行到哪一行代码
栈:
本地方法栈:本地的方法。如:线程启动的start()方法。
在这里插入图片描述

1.2 本地方法栈

Java 虚拟机栈:Java 虚拟机栈为虚拟机执行 Java 方法(也就是字节码)服务,
本地方法栈:登记本地Native 方法,在execution engine执行的时候加载本地方法库。

1.3 堆

堆是用来存储对象实例以及数组
在开发过程使用的new对象,只要通过new创建的对象的内存的对象都在堆分配
堆是Java垃圾收集器管理的主要区域,Java的垃圾回收机制会自动进行处理。

1.3.1 堆内部结构:年轻代和老年代

堆空间分为老年代(2/3)和年轻代(1/3)
老年代内存:年轻代内存 2:1
年轻代:8:1:1

在这里插入图片描述

1.3.2 垃圾回收机制(GC)

Minor GC:如果 Eden 空间占满了, 会触发 minorGC。 MinorGC 后仍然存活的对 象会被复制到 S0 中去。这样 Eden 就被清空可以分配给新的对象。 又触发了一次 MinorGC , S0 和 Eden 中存活的对象被复制到 S1 中, 并且 S0 和 Eden 被清空。(复制算法

当每次对象从Eden复制到SurvivorSpace或者从SurvivorSpace中的一个复制 到另外一个,有一个计数器会自动增加值。 默认计数达到15时,就会把对象转移到老年代中去。

Full GC:老年代的空间被占满会触发老年代的 GC,也被称为 FullGC。FullGC 是一个 压缩处理过程,所以它比 MinorGC 要慢很多。“标记-清除(Mark-Sweep)”的算法。

一次Full GC就需要把进程停掉,STW(stop the world),这个时间时非常久的,所以要尽量避免Full GC

1.4 方法区

属于共享内存区域
存储常量、静态变量、类元信息

1.5 程序计数器

多线程是通过线程轮流切换来获得CPU执行时间的,在任一具体时刻,一个CPU的内核只会执行一条线程中的指令,因此,为了能够使得每个线程都在线程切换后能够恢复在切换之前的程序执行位置,每个线程都需要有自己独立的程序计数器,并且不能互相被干扰,否则就会影响到程序的正常执行次序。

2.垃圾回收机制

2.1 判断是否为垃圾

2.1.1 引用计数法和可达性分析法

判断对象是否为垃圾
目前虚拟机基本上都用可达性分析法。
引用计数法:每个对象都有一个引用计数器,对象引用一次计数加1,引用失效一次计数减1,当GC时,计数器为0的对象就可以被回收。

可达性分析法:从GC ROOT起点出发,可以遍历到的节点对象标记,未标记/没有遍历到的对象就是可以被回收的对象。

有些对象的引用计数不为0,但是永远不会被访问了(类似在可达性分析法中,GC ROOT已经消除了,原来GC ROOT下面的节点就不会在被访问),这时用引用计数法就无法清除,可达性分析法可以。

2.2 垃圾收集的方法

2.2.1 复制算法

(在Minor GC中),它将可用内存按照容量划分为大小相等的两块,每次只使用其中的一块。当这一块的内存用完了,它将还存活着的对象复制到另一块上面,然后再把已经使用过的内存空间一次性清理掉。

2.2.2 标记-清除

(在Full GC中),没有与GC Roots相连接的引用链的对象就是未标记的对象,然后在将未标记的对象删除
缺点有两个:一个是效率问题,标记和清除这两个过程的效率都不高;另外一个是碎片问题,标记清除之后会产生大量不连续的内存碎片,可能会导致程序在以后的运行过程中需要分配较大对象时由于无法找到足够的连续内存而不得不提前触发另一次垃圾收集动作

2.2.3 标记-整理

1.复制收集算法在对象存活率较高时就要执行较多的复制操作,效率将会变低
2.老年代都是不易被回收的对象,对象存活率高,因此一般不能直接选用复制算法
标记过程仍然与"标记-清除"算法一样,但后续整理过程不是直接对可回收对象进行清理,而是让所有存活的对象都向一端移动,然后直接清理掉端边界以外的内存。

2.2.4 分代收集

不是新的方法,就是上面方法的组合,根据年轻代和老年代的特点采用最适当的收集算法
在新生代中,每次垃圾收集时都有大批对象死去,只有少量存活,那就选用复制算法。而老年代对象存活率高、没有额外空间对它进行分配担保,就必须使用"标记-清除"或"标记-整理"算法来进行回收。

猜你喜欢

转载自blog.csdn.net/weixin_45773603/article/details/108052103