jvm总结学习

四种加载器

1.启动类加载器

2.拓展类加载器

3.应用程序加载器

4.自定义加载器

沙箱机制

就是为了保证安全,增加的一些权限。

native方法区(静态变量,常量,类信息(构造方法,接口定义),运行时的常量池)

1.凡是带了native的关键字,说明java的作用范围达不到了,会去底层调用C语言的库。

2.会进入本地方法栈

3.调用本地方法本地接口 JNI

4.JNI作用:会拓展java的使用融合不同的编程语言为Java使用! 最初是C C++

java诞生的时候,C C++横行 ,想要立足,必须要有调用 C C++的方法

5.它在内存区专门开辟了一个空间 Native Method Stack 来标记native方法,

6.在最终执行的时候,加载本地方法库中方法通过JNI

堆(重点)

一个jvm只有一个堆,堆的大小可以调节, 一般 类,方法,常量,变量 ,保存我们所有引用类型的真实对象;

堆内存还分为3个区域;

新生区

老年区

永久区 用来存在JDK字自身携带的Class对象。interface元数据,存储的是java运行时的一些环境或者类信息。

GC垃圾回收,主要是在新生区和老年区

在JDK1.8之后 永久区改为元空间 方法区在元空间中 常量池在方法区中

元空间只在逻辑上存在,物理上是不存在的。

如果出现OOM 堆内存溢出 怎么解决:

1.尝试扩大内存看结果,

2.分析内存,看下哪个地方出现了问题(死循环,递归调用之类的)

GC

什么是GC root?

JVM在垃圾回收的时候,需要找到"垃圾"对象,也就是没有被引用的对象,但是直接找垃圾对象是比较耗时间的,所以反过来找,先找非垃圾对象,也就是正常的对象,那么就要从某些"根"去找,根据这些根的引用路径找到正常的对象,而这些根有个特征,就是它会引用其他的对象,而不会被其他的对象引用,例如:栈中的本地变量,方法区的静态变量,本地方法栈的变量,正在运行的线程等都可以作为GC root;

jvm在进行垃圾回收的时候,并不是对这三个区域统一回收。大部分的时候,回收的都是新生代

三个区域进行垃圾回收

新生代

幸存区

老年区

GC 分为两种 轻GC(普通的GC),重GC(全局的GC)

GC题目:

JVM内存模型和分区~详细到每个区都放什么?(看上面的图片)

堆里面的分区有哪些? Eden,form,to,old,说说他们的特点!

GC的算法? 标记-清除法,标记整理,复制算法,引用计数法(不常用) 这些怎么用的?(下面有详细的工作原理介绍)

轻GC和重GC分别在什么时候发生?

轻GC是在新生区、存活区进行发生的。

重GC是在新生区、存活区、老年区进行发生的。

复制算法:

新生区 :幸存区(from):幸存区(to)=8:1:1 原理就是在新生区产生的内存放在幸存区from中,然后两个幸存区 ,谁的空间是空的 谁就是to区 ,在内存不断的生成中,两个幸存区来回交换,即:最终保留一个to区 也就是空的,另外一个from存放的就是活下来的数据。

好处:没有内存的碎片

坏处:浪费了内存的空间:多了一半空间永远是空的to区

试用的场景:对象存活度较低的时候:新生区

标记-清除算法:

好处:不需要额外的空间。

坏处:两次扫描,严重浪费时间,会产生内存碎片。

试用的场景:对象存活度较低的时候:新生区

JVM1.7和1.8java虚拟机发生了哪些变化?

1.7中存在永久代,1.8改为元空间,元空间所占的内存不是虚拟机内部,而是本地内存空间,不管是永久代还是元空间,他们都是方法的具体实现,之所以元空间所占的内存改为本地内存,官方的说法是为了和JRockit统一,不过还有其他的一些原因,比如:方法区所存储的类信息通常是比较难确定的,所以对于方法区的大小是很难确定的,太小了容易出现方法区的溢出,太大了又会占用虚拟机更多的 空间,而转移到本地,则不会影响虚拟机所占的内存。

总结

内存效率:复制算法>标记清除算法>标记整理(压缩)算法 说白了 就是比较 时间复杂度

内存整齐度:复制算法=标记整理(压缩)算法 >标记清除算法 说白了 就是比较 内存连不连续

内存利用率:标记清除算法 =标记整理(压缩)算法 >复制算法

没有最优的算法,只有最合适的算法------>GC:分代收集算法

年轻代:

存活率低

复制算法!

老年代:

区域大:存活率

标记清除(内存碎片不是很多)+标记压缩(整理) 混合实现

判断 对象是否存活

引用计数法---------每当有一个地方引用它时,计数器值就加1,当索引失效时,计数器就减1;任何时刻计数器为0的对象就不可能再被使用。

可达性分析算法---------这个算法的基本思路就是通过一系列的称为"GC Roots"的对象作为起始点,从这些节点开始向下搜索,搜索走过的路径称为引用链,当一个对象到GC Roots没有任何引用链相连时(按照图说的话,就是从GC Roots到这个对象不可达),则证明这个对象是不可用的,如下图,obj5、obj6、obj7、虽然互相有关联,但是都是GC Roots是不可达的,所以他们将被判定为可回收的对象。

垃圾回收算法

标记-清除算法(Mark-Sweep)---最基础的算法,分为两个阶段,标注和清除,标注阶段标出所有需要清除的对象,清除阶段会回收被标记对象所占用的空间

复制算法---为了解决Mark-Sweep算法内存碎片化的缺陷而被提出的算法。将内存容量将内存划分为等大小的两块。每次只使用其中一块,当这一块内存满后将尚存活的对象复制到另一块上去,把已经使用的内存清掉,如图

标记-整理算法(Mark-Compact) -------结合了以上的两个算法,为了避免缺陷而提出。标记阶段和Mark-Sweep算法相同,标记后不是清理对象,而是将存

活对象移向内存的另一端。然后清除边界外的对象。如图

分代收集算法(Generational Collection)重要

分代收集算法是目前大部分JVM所采用的算法,其核心思想是根据对象存活的不同生命周期将内存划分为不同的域,一般情况下将GC堆划分为老年代和新生代。

老年代的特点就是在垃圾回收时只有少量的对象需要被回收。

新生代的特点就是在回收时都有大量垃圾需要被回收,因此可以根据不同的区域选择不同的算法。

目前大部分的jvm的GC对于新生代都采用Copying算法,因为新生代中每次垃圾回收都要回收大部分对象,即要复制的操作比较少,当通常不是按照1:1划分新生代。一般将新生代划分为一块较大的Eden空间和两个较小的Suivior空间,每次使用Eden空间和其中的一块Survivor空间,当进行回收时,将该两块空间中还存活的对象复制到另一块Survivor空间中。

相关推荐
●VON1 分钟前
重生之我在大学自学鸿蒙开发第一天-《基础篇》
学习·华为·harmonyos·鸿蒙
用户9047066835714 分钟前
如何使用 Spring MVC 实现 RESTful API 接口
java·后端
刘某某.15 分钟前
数组和小于等于k的最长子数组长度b
java·数据结构·算法
程序员飞哥20 分钟前
真正使用的超时关单策略是什么?
java·后端·面试
用户9047066835722 分钟前
SpringBoot 多环境配置与启动 banner 修改
java·后端
小old弟43 分钟前
后端三层架构
java·后端
花花鱼44 分钟前
spring boot 2.x 与 spring boot 3.x 及对应Tomcat、Jetty、Undertow版本的选择(理论)
java·后端
温柔一只鬼.1 小时前
Docker快速入门——第二章Docker基本概念
java·docker·容器
要争气1 小时前
5 二分查找算法应用
java·数据结构·算法
ooo-p1 小时前
FPGA学习篇——Verilog学习之分频器的实现
学习·fpga开发