JVM初探

1 JVM的位置

在这里插入图片描述
JVM处于操作系统之上,相当于一个运行Java编译过之后的class文件的软件

2 JVM 的体系结构

在这里插入图片描述

在这里插入图片描述
总结:栈内不回头GC , 大多数GC都在堆内;方法区相当于特殊的堆

程序计数器每一个线程都有一个程序计数器,线程私有,本质上就是一个指针,指向方法区中的方法字节码(用来存储指向下一条指令的地址),内存很小,几乎可以忽略不计
方法区方法区被所有的线程共享,所有的字段和方法字节码,一些特殊的方法,如 构造函数和接口代码·,简单的说:所有定义的方法的信息都保存在该区域,该区域是共享区域
静态变量,常量,类信息(构造函数,接口定义),运行时的常量池都存在于方法区中,但是实例变量存在于栈中,与方法区无关
static final Class模板 常量池

3 类加载器

作用:加载经过编译后产生的class文件
在这里插入图片描述
Class 类是抽象且唯一的,new 出来的实例是具体且多样的;相当于Class 对象是一个模板,而new 出来的对象就是具体的东西,
而且过程可逆

类加载器的类别
BootstrapClassLoader(启动/根类加载器)
c++编写,加载java核心库 java.*,构造ExtClassLoader和AppClassLoader。由于引导类加载器涉及到虚拟机本地实现细节,开发者无法直接获取到启动类加载器的引用,所以不允许直接通过引用进行操作

ExtClassLoader (标准扩展类加载器)
java编写,加载扩展库,如classpath中的jre ,javax.*或者
java.ext.dir 指定位置中的类,开发者可以直接使用标准扩展类加载器。

AppClassLoader(系统类加载器)
java编写,加载程序所在的目录,如user.dir所在的位置的class

CustomClassLoader(用户自定义类加载器)
java编写,用户自定义的类加载器,可加载指定路径的class文件

4 双亲委派机制:

当某个类加载器需要加载某个.class文件时,它首先把这个任务委托给他的上级类加载器,递归这个操作,如果上级的类加载器没有加载,则抛出异常,通知子类加载器去加载这个类

双亲委派机制的作用
1、防止重复加载同一个.class。通过委托去向上面问一问,加载过了,就不用再加载一遍。保证数据安全。
2、保证核心.class不能被篡改。通过委托方式,不会去篡改核心.clas,即使篡改也不会去加载,即使加载也不会是同一个.class对象了。不同的加载器加载同一个.class也不是同一个Class对象。这样保证了Class执行安全。

5 Native关键字

如果出现native关键字,则说明Java的作用范围达不到了,需要调用底层由C语言写的本地方法库
调用流程
1 先进入本地方法栈
2 通过本地方法接口(JNI)来调用本地方法库

JNI的作用
为了融合其它的语言被Java调用
历史
在Java诞生之初,C,C++横行,为了融合C ,C++ 专门开辟了一个内存空间(本地方法栈),来记录本地方法,在最后加载时通过JNI来加载本地方法库

6 栈

特点: 先入后出
主管程序的运行,生命周期与线程同步,线程结束,栈空间就释放,所以栈不可能有GC
运行原理:栈帧,就是一个方法在栈空间所占的空间
存储内容: 八大基本类型,对象的引用,实例的方法
在这里插入图片描述
在这里插入图片描述
对象实例化过程
编译期间,会生成Student.class字节码文件。

初始化时:

1、类加载器ClassLoader,加载Student.class字节码到内存;

2、在栈里面为变量s申请一个空间,用来声明s;

3、new的时候,在堆内开辟空间。然后,开始进行默认初始化,String类型默认给null,int类型默认给0等。默认初始化后,开始进行显示初始化,比如成员变量里name默认值为Alice,所以这时会初始化name为Alice。

3、执行Student()构造方法,构造方法进栈,进行构造方法初始化

4、执行构造方法初始化,构造方法执行完毕后出栈,把堆内的对象物理地址,复制给栈内的s,也就是s存放的是对象的引用(物理地址)。

5、执行Student里面的方法时,方法进栈,方法里隐式的this指向堆内存空间

7 堆

在这里插入图片描述
轻量级GC针对于新生区,重量级GC针对于幸存区
GC的作用范围主要位于新生区和幸存区,在JDK8以后,永久存储区改为元空间,本质上有一点点不同

新生区
1 伊甸园区:一个对象出生,成长,死亡的区域
2 幸存0区:当伊甸园区满了之后就会触发一次轻GC,幸存下来的就会进入幸存0区
3 幸存1区:幸存0区和幸存1区动态交换
当触发一次重GC之后就会对幸存0区和幸存1区进行一次交换

养老区
当幸存区满了之后就会触发一次重GC,在重GC幸存下来的对象就会进入养老区,当养老区满了之后就报OOM(OverOfMemoryError)

元空间:逻辑上存在,物理上不存在

1. ## 堆完整图

在这里插入图片描述
在这里插入图片描述
方法区内还有常量池

JVM内存调节
在这里插入图片描述
参数之间有空格,下面有正确的参数
在这里插入图片描述
在这里插入图片描述
Dump出文件的参数
在这里插入图片描述
综合参数
在这里插入图片描述

8 GC

JVM在进行GC时,并不是进行对三个区域都进行GC,而是大多数GC都在新生区

8.1 GC题目

1 JVM的内存模型和分区,详细到每一个分区应该放什么
2 堆里面的分区有哪些? Eden(伊甸园区)from(幸存0区) to(幸存1区) 养老区 ,说说各自的特点?
3 GC的算法有哪些 ? 标记清除法 标记压缩法 引用计数法 复制算法,怎么用?
4 轻GC 和 重GC 什么时候发生?

8.2 GC算法

1 引用计数法
在这里插入图片描述

2 复制算法
在这里插入图片描述

在这里插入图片描述
总结:每一次GC之后,Eden区幸存下来的对象就会进入to区,然后from区幸存下来的对象也会用复制算法复制到to区,所以from区就会变为空,这时from区和to区就会交换位置,空的区域始终是to区
默认在from区到to区时会判断一下,幸存15次就会进入养老区

优点:没有内存的碎片
缺点:浪费了内存空间,有一个区域一直为空
最佳使用场景:对象存活度较低的区域(新生区)

3 标记清除算法
在这里插入图片描述
第一步 :扫描所有对象,幸存的对象进行标记
第二步 :对于没有被标记过的对象进行清除

优点:节省空间
缺点:两次扫描,严重浪费时间,会产生内存碎片

4 标记压缩算法

优点:对于标记清除后产生的内存碎片进行整理,使得内存碎片不存在
缺点:进行了三次扫描

算法总结

时间复杂度: 复制算法 > 标记清除算法 > 标记整理算法
内存整齐度: 复制算法 = 标记整理算法 > 标记清除算法
内存利用率: 标记清除算法 = 标记整理算法 > 复制算法

GC 的算法 分代收集算法

新生区 : 存活率低
适用于 复制算法

养老区 : 存活率高
适用于 标记清除算法+标记整理算法 (多清除之后再整理)

9总结:

在这里插入图片描述
指定次数:在YGC下,幸存次数超过默认次数的对象放入old区,默认为15次
动态年龄: from区的空间占用率超过50%时 ,在进行YGC时,把年龄最大的对象放入old区

YGC的触发条件:
1 Eden区剩余空间放不下新的对象
2

FGC的触发条件
1 Old区剩余空间放不下新的对象

1 幸存15次上来的对象
2 经过动态年龄上来的对象
3 Eden区放不下,直接上来的对象

2 系统调用System.gc 可能调用

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值