初步认识JVM~

1.JVM是干啥的

在这里插入图片描述
JVM出现的初心是为了跨平台,一次开发,到处运行。
Linux和Windows的JVM是不一样的。
按理说,不同的平台之间,差异是很大的.
JVM屏蔽了系统和硬件.上的差异.
1.操作系统:不同的系统API差别很大.
2.硬件(CPU架构):不同的CPU也不太- -样.
JVM类似于一个“翻译官

现在来看,JVM存在的意义已经不仅仅是为了跨平台了,而是提供了-个“生态圈"
JVM能够屏蔽系统的差异,发明一-些新的语言,也想跨平台,就可以直接借助JVM来完成,而无需自己考量.
只要让这个语言编译生成的是和JVM匹配的字节码,此时就可以直接借助JVM来运行你的语言.
同时也能保证,Java中现成的海量的第三方库,也就同时都能使用了.

一个JVM中包含这几个主要的部分:
1.类加载器
2.执行引擎(解释执行字节码)
3.动态内存管理器

JVM中的内存区域划分:
JVM内存来自于操作系统,JVM启动之后就会从操作系统申请一大块内存,在针对这个内存划分出一些区域。

1.堆(运行时常量池)
new的对象就放到堆中
2.方法区
加载好的类放在方法区中,静态变量也在
3.栈(JVM栈,本地方法栈)
局部变量
4.程序计数器
存的是地址,描述当前线程接下来要执行的指令在内存的哪个地方。

一个java进程中可能包含着多个线程、
多个线程之间,共用同一份堆和方法区.
但是每个线程有 自己的栈和程序计数器.

决定某个变量,是在栈上还是堆上和这个变量是基础类型还是引用类型无关,和这个变量是局部变量还是成员变量还是静态变量有关.

在这里插入图片描述
常见面试题:
1.如何理解基础数据类型和引用数据类型
引用中存的是地址,
在这里插入图片描述
2.如何理解 局部变量,成员变量,静态变量?
a.局部变量在栈上
b.成员变量在堆上
c.静态变量在方法区
3.static方法和普通方法之间的区别?
普通方法中有this,和实例相关,也叫实例方法
static方法中没有this,和类相关,和实例无关,也叫类方法。

2.JVM中的垃圾回收机制(GC)

C语言中的内存,申请之后,需要手动释放.
Java中的内存,申请之后,不需要手动释放. (GC),有利于避免内存泄漏,
但是C语言和c++为啥不引入这个GC呢,
因为引入他需要消耗更多资源,也没有手动释放更加及时,也会影响到正常程序工作。

1.GC主要回收哪些内存?
主要回收这个
方法区 需要回收,但是空间小,效率低
不需要回收,栈上的内存何时释放时机是明确的
程序计数器 只是存了一个地址,不需要回收

2.回收内存的基本单位
他不是按照字节来回收的,而是按照对象的方式来回收。
每个对象,都持有了一定的内存. 释放对应的对象,也就回收了对应的内存.
在这里插入图片描述
3.回收对象的基本思路
a.标记:找出这个对象是否需要回收(判断对象生死)
b.回收:把死了的对象回收回去

标记方法:

1.引用计数法
记录这个对象,是否有引用指向,有几个,每次该对象被引用指向,就会加一,每个对象都专门分配一个计数器变量。
但有个致命的缺陷,无法解决循环引用的问题。
在这里插入图片描述

2.可达性分析(Java中使用的方式)
代码中的对象之间是有一定关联关系的,这样的关联关系错综复杂构成了一个有向图。遍历这个对象关系的图,如果某个对象可以被遍历到,就不是垃圾(可达的).
如果无法被遍历到,就是不可达.

从哪开始遍历:
1.针对每个线程的每个栈帧的局部变量表
2.常量池中引用的对象
3.方法区中静态变量引|用的对象.
遍历的起点不是一个,而是很多起点.
把每个起点都要进行往下遍历.
统称为GCRoot

回收方式:

1.标记之后直接清除,
在这里插入图片描述
2.标记后复制
在这里插入图片描述
然后就可以把之前的整体都给释放掉,这可以解决内存碎片问题,但是需要额外的内存空间,如果生存对象较多,效率就比较低。
3.标记后整理
在这里插入图片描述
把不存活的释放,然后把后面对象往前搬运,把碎片挤掉,类似顺序表的删除,又解决了上一个方法问题。

我们可以进行垃圾分类:
把内存中的垃圾对象分成几个类别,不同类别,分别使用不用的回收算法。

分代回收:
按照对象年龄把堆内存分成 新生代 老生代
在这里插入图片描述
一个对象的一生~~
1.对象诞生于新生代伊甸区.新对象的内存就是新生代中的内存.
2.第- -轮GC扫描伊甸区之后,就会把大量的对象干掉(统计发现,绝大部分对象都是"朝生夕死")
少数没有干掉的对象,就会被拷贝到生存区(标记复制算法) (例如先拷贝到生存区1)
3.进入生存区的对象,也会被GC进行扫描
两个生存区就是为了更好地去来回复制
4.经过若干次轮次拷贝,也没被回收,就拷贝到了老年代
5、也是要经历GC扫描的,由于存活时间比较长,扫描花费的时间也就比较长。

垃圾回收器:

评价垃圾回收器好坏的标准:
1.回收的空间效率.扫- -遍地,能扫出多少垃圾.
2.回收的速度.扫- -遍地要花多长时间.
3.垃圾回收和应用线程之间能否并发执行.扫地的时候会不会影响到别人干活(STW)
4.垃圾回收器是否是多线程的.
5.回收的时间是否是可预测的.承诺10分钟之内一定把地扫完.即使扫的不算非常干净,但是也最大程度上的把一些重要的垃圾清理掉了.

垃圾回收器里面都是要做两件事:标记(可达性分析) +回收(标记清除,标记复制,标记整理)

  1. Serial收集器.给新生代使用,串行回收.(复制算法,单线程标记+回收)

在这里插入图片描述

  1. ParNew收集器(新生代收集器多线程进行GC)

深拷贝和浅拷贝:

深拷贝:针对对象A拷贝之后得到对象B,对A的修改不会对B造成任何影响.这种就叫深拷贝.

浅拷贝:针对对象A拷贝之后得到对象B,对A的修改会影响到B.

3.JVM中的类加载过程

在这里插入图片描述
加载过程:
1.加载:根据类名找到文件,读取文件,解析架构,把内容放到内存中,并构架出对应类对象。
2.链接:如果该类依赖了一些其他类,链接过程就是把依赖内容引用
3.初始化:初始化静态成员,并且执行静态代码块

关于类加载常见面试题:

1.是么时机会触发某个类的加载
a>构造该类实例
b>调用该类的静态属性或者方法
c>使用子类会触发父类加载

class AA{
    public AA() {
        System.out.println("AA.构造");
    }
    {
        System.out.println("AA.{}");
    }
    static {
        System.out.println("AA.static {}");
    }
}
class BB extends AA{
    public BB() {
        System.out.println("BB.构造");
    }
    {
        System.out.println("BB.{}");
    }
    static {
        System.out.println("BB.static {}");
    }
}
public class Demo2 extends BB{
    public static void main(String[] args) {
        System.out.println("开始");
        new BB();
        new BB();
        System.out.println("结束");
    }

}

在这里插入图片描述
在这里插入图片描述
AA.static {}
BB.static {}
开始
AA.{}
AA.构造
BB.{}
BB.构造
AA.{}
AA.构造
BB.{}
BB.构造
结束

class AA{
    public AA() {
        System.out.println("AA.构造");
    }
    {
        System.out.println("AA.{}");
    }
    static {
        System.out.println("AA.static {}");
    }
}
class BB extends AA{
    public BB() {
        System.out.println("BB.构造");
    }
    {
        System.out.println("BB.{}");
    }
    static {
        System.out.println("BB.static {}");
    }
}
public class Demo2 {
    public static void main(String[] args) {
        System.out.println("开始");
        new BB();
        new BB();
        System.out.println("结束");
    }

}

开始
AA.static {}
BB.static {}
AA.{}
AA.构造
BB.{}
BB.构造
AA.{}
AA.构造
BB.{}
BB.构造
结束

2.类加载器有哪些?

  1. BootstrapClassLoader

在这里插入图片描述
没法通过getClassLoader获取到。
2. ExtClassLoader

在这里插入图片描述

  1. ApplicationClassLoader

在这里插入图片描述

这三个各自负责自己的一篇区域

BootstrapClasslpader: D:\jdk1.8Vire\ib\tjar 标准库中的类的实现就在这个rt.jar中.
ExtClassLoader: D:\jdk1.8\jre\ib\ext 的所有jar包中找
AppClassLoader: 1) CLASS_ PATH环境变量(很少配置) 2)java -cp 3). 当前目录

3.啥事双亲委派模型

描述的是类加载中,根据类名找类的.class的文件查找过程

在这里插入图片描述
这样做的目的就是为了尽量让标准库中的类优先被加载

4.能否违背双亲委派模型?
可以违背,只是标准库中的三个类加载器要遵守,其他类加载器不太需要遵守

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

lhj_loveFang_1105

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值