八股文5:JVM

文章目录

java是编译+解释共存的语言

在这里插入图片描述
在这里插入图片描述
.class文件(jvm可读的二进制文件)和JVM生成的可读的字节码(指令)文件的区别

.class文件(16进制)

在这里插入图片描述

字节码文件(可阅读的指令文件)
注意:程序计数器指向的就是这个字节码指令的每行的运行的位置
在这里插入图片描述

Java虚拟机栈异常的情况

在这里插入图片描述

注意:一般Java虚拟栈一般在线程运行时是不会出现栈内存的溢出的,除非创建新线程申请内存时因内存不足就直接抛出OOM。运行时,一般只会抛出stackOverFlow的异常,就是超过了栈的深度,新的栈帧已经无法入栈

在这里插入图片描述

针对死归,会出现stackoverFlow

在这里插入图片描述

针对创建过多的线程出现栈内存溢出的情况
在这里插入图片描述

在这里插入图片描述

堆内存异常情况

在这里插入图片描述

在这里插入图片描述

针对堆内存OOM可以解决分析的步骤:
在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

内存泄漏和内存溢出

在这里插入图片描述
注意:内存泄露会最终导致内存溢出
在这里插入图片描述

GC日志打印

在这里插入图片描述

[0.008s][info][gc] Using G1
[0.009s][info][gc,init] Version: 16.0.2+7-67 (release)
[0.009s][info][gc,init] CPUs: 8 total, 8 available
[0.009s][info][gc,init] Memory: 16167M
[0.009s][info][gc,init] Large Page Support: Disabled
[0.009s][info][gc,init] NUMA Support: Disabled
[0.009s][info][gc,init] Compressed Oops: Enabled (Zero based)
[0.009s][info][gc,init] Heap Region Size: 2M
[0.009s][info][gc,init] Heap Min Capacity: 8M
[0.009s][info][gc,init] Heap Initial Capacity: 254M
[0.009s][info][gc,init] Heap Max Capacity: 4042M
[0.009s][info][gc,init] Pre-touch: Disabled
[0.009s][info][gc,init] Parallel Workers: 8
[0.009s][info][gc,init] Concurrent Workers: 2
[0.009s][info][gc,init] Concurrent Refinement Workers: 8
[0.009s][info][gc,init] Periodic GC: Disabled
[0.009s][info][gc,metaspace] CDS archive(s) mapped at: [0x0000000800000000-0x0000000800bb0000-0x0000000800bb0000), size 12255232, SharedBaseAddress: 0x0000000800000000, ArchiveRelocationMode: 0.
[0.009s][info][gc,metaspace] Compressed class space mapped at: 0x0000000800c00000-0x0000000840c00000, reserved size: 1073741824
[0.009s][info][gc,metaspace] Narrow klass base: 0x0000000800000000, Narrow klass shift: 3, Narrow klass range: 0x100000000
Java HotSpot(TM) 64-Bit Server VM warning: Options -Xverify:none and -noverify were deprecated in JDK 13 and will likely be removed in a future release.
[0.477s][info][gc,start    ] GC(0) Pause Young (Normal) (G1 Evacuation Pause)
[0.477s][info][gc,task     ] GC(0) Using 6 workers of 8 for evacuation
[0.480s][info][gc,phases   ] GC(0)   Pre Evacuate Collection Set: 0.0ms
[0.480s][info][gc,phases   ] GC(0)   Merge Heap Roots: 0.0ms
[0.480s][info][gc,phases   ] GC(0)   Evacuate Collection Set: 2.9ms
[0.480s][info][gc,phases   ] GC(0)   Post Evacuate Collection Set: 0.4ms
[0.480s][info][gc,phases   ] GC(0)   Other: 0.3ms
[0.480s][info][gc,heap     ] GC(0) Eden regions: 11->0(13)
[0.480s][info][gc,heap     ] GC(0) Survivor regions: 0->2(2)
[0.480s][info][gc,heap     ] GC(0) Old regions: 0->1
[0.480s][info][gc,heap     ] GC(0) Archive regions: 0->0
[0.480s][info][gc,heap     ] GC(0) Humongous regions: 0->0
[0.480s][info][gc,metaspace] GC(0) Metaspace: 7502K(7744K)->7502K(7744K) NonClass: 6580K(6720K)->6580K(6720K) Class: 922K(1024K)->922K(1024K)
[0.480s][info][gc          ] GC(0) Pause Young (Normal) (G1 Evacuation Pause) 22M->5M(254M) 3.733ms
[0.480s][info][gc,cpu      ] GC(0) User=0.00s Sys=0.00s Real=0.00s

java内存区域

java内存的具体结构(注意版本的更新)

注意:是运行时的数据区域,不是编译期也不是类加载期(感觉类加载就是二进制文件翻译成可阅读的字节码文件)

在这里插入图片描述

1.java虚拟机栈(每个方法对应的栈帧)—线程私有

在这里插入图片描述

2.堆内存(new 出来的实例对象)–线程共享

在这里插入图片描述

3.方法区(HotSpot永久代)–线程共享

在这里插入图片描述

4.一些勘误更改

注意:方法区是JVM的规定叫法,永久代是Hotspot虚拟机的叫法(别的虚拟机可能根本没有永久代这个概念)
元空间使用的是直接内存,受本机可用内存的限制
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

对象的创建(new出来的对象都在堆中)

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
TLAB:Threadlocal allocate buffer

在这里插入图片描述

对象头的组成:3个部分Markword(hashcode,synchronized的锁升级)+指向类的指针(属于哪个类)+数组的长度
在这里插入图片描述

在这里插入图片描述

对象访问的定位方式

句柄定位:reference存放的是句柄地址(稳定)
在这里插入图片描述

直接指针定位:reference存放的是直接对象的地址(速度快)
在这里插入图片描述
在这里插入图片描述

string的注意点

equals()方法

注意String的hashcode()方法是重写过的,相同的字符串内容具有相同的hash码,但是内存地址不一定相同!!!
注意intern()方法是相对于String变量来说的,不然谁还调用它;没有调用的字符串变量对象创建就是在堆内存

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

常量折叠的优化(基本数据类型+字符串常量+final修饰的字符串变量)

注意引用不能常量折叠的优化,原因:引用的值在程序编译期是无法确定的,编译器无法对其进行优化。
在这里插入图片描述

final修饰的字符串常量(注意是否可以在编译期就确定,否则无法“常量折叠”的优化)

在这里插入图片描述

字符串拼接问题

在这里插入图片描述

宋红康版本–拼接讲解

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

intern方法(注意版本的区别)—注意和下一个问题一起理解

仅针对,构造了字符串变量时,将字符串变量调用intern()方法,针对正常的创建字符串变量还是会创建在堆中
在这里插入图片描述

宋红康版本的intern讲解

在这里插入图片描述

jdk6池中没有此字符串,将堆中的“对象的内容”赋复制一份到字符串常量池中,并返回池中的对象地址

在这里插入图片描述

jdk7池中没有此字符串,把堆中的“引用地址”复制一份到字符串常量池中,返回池中的这个“引用地址”

在这里插入图片描述

池中都有此字符串,返回字符串常量池中对象的地址

在这里插入图片描述

String s1 = new String(“abc”);这句话创建了几个字符串对象?

注意:new出来的对象都在堆中
在这里插入图片描述

垃圾回收

分代回收的具体过程

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

垃圾回收器的分类

在这里插入图片描述

注意:一般新生代回收器都是复制算法,因为存活的对象比较少,采用复制算法比较快;老年代一般采用压缩整理算法,原因可能出现新生代中大对象直接去老年代的情况,没有内存碎片问题,空间足够的大!!
在这里插入图片描述

在这里插入图片描述

吞吐量和暂停时间的关系

在这里插入图片描述

在这里插入图片描述

宋红康笔记

1.年轻代垃圾回收器

Serial

在这里插入图片描述

ParNew

在这里插入图片描述

Parallel Scavenge(适合后台运算—高吞吐量—高CPU效率)

在这里插入图片描述
在这里插入图片描述
设定一定的参数实现自适应
在这里插入图片描述

2.老年代CMS(Concurrent-Mark-Sweep)—(停顿时间短–适用于用户交互)

在这里插入图片描述
在这里插入图片描述
宋红康版本
在这里插入图片描述
在这里插入图片描述

不需要移动存活对象就可以避免“对象消失”的问题“”
在这里插入图片描述

3.G1回收器:区域化分代式(新生代+老年代)

总体特征

在这里插入图片描述

优势

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

缺点

在这里插入图片描述

具体过程(并发标记阶段的原始快照+region按照指针分配新的对象)

在这里插入图片描述

解决跨代引用问题和跨区域引用的问题(记忆集与卡表)

在这里插入图片描述

在这里插入图片描述

记忆集是一种用于记录从非收集区域指向收集区域的指针集合的抽象数据结构
在这里插入图片描述

解决“并发标记过程”的“对象消失”问题(CMS&G1)

对象消失

类文件结构(.class文件)–非重点

在这里插入图片描述

总结一下:魔数+主次版本号+常量池及其数量+访问权限标志及本类父类+实现的接口及其数量+字段及其数量+方法机器数量+属性表集合

在这里插入图片描述

类文件加载过程(虚拟机是如何加载这些 Class 文件的)

类加载比创建对象更早,没有类对象,没办法实例化创建对象

生命周期

在这里插入图片描述

类加载过程

在这里插入图片描述

简略版本

在这里插入图片描述

加载阶段和连接阶段的部分内容是交叉进行的,加载阶段尚未结束,连接阶段可能就已经开始了

1.加载(3件事情)

在这里插入图片描述

获取二进制数据流的方式不唯一

在这里插入图片描述

数组类的创建

在这里插入图片描述

2.1链接–验证

在这里插入图片描述
在这里插入图片描述

2.2链接–准备(区别于初始化阶段的赋值)

注意:类变量,也就是静态变量,属于多个实例对象的共享对象(放在线程共享的方法区)
在这里插入图片描述

2.3链接–解析

将符号引用,转换为指向对象的内存地址值
在这里插入图片描述

3.初始化

类加载的初始化是,即构造器constructor的initial阶段;区别于对象创建的方法,程序给对象初始化
在这里插入图片描述

总结一下:new, static的任何相关,反射某个类的相关信息,父类未初始化,含有main方法的主类,某个实现类的接口
在这里插入图片描述

类的卸载(比较困难)—详情请见“类加载器”

在这里插入图片描述

类加载器详解(双亲委派模型)

所有的类都由“类加载器”加载,加载的作用就是将 .class文件加载到内存

类的唯一性==类本身&&类加载器

在这里插入图片描述

类加载器的分类

在这里插入图片描述
在这里插入图片描述

双亲委派模型

在这里插入图片描述
在这里插入图片描述
Java类随着它的类加载器一起具备了一种带有优先级的层次关系,通过这种层级关可以避免类的重复加载,当父亲已经加载了该类时,就没有必要子ClassLoader再加载一次。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
一个自定义类的类加载器的高优先级的类加载器,类加载器之间的“父子”关系也不是通过继承来体现的,是由“优先级”来决定。

public class ClassLoaderDemo {
    public static void main(String[] args) {
        System.out.println("ClassLodarDemo's ClassLoader is " + ClassLoaderDemo.class.getClassLoader());
        System.out.println("The Parent of ClassLodarDemo's ClassLoader is " + ClassLoaderDemo.class.getClassLoader().getParent());
        System.out.println("The GrandParent of ClassLodarDemo's ClassLoader is " + ClassLoaderDemo.class.getClassLoader().getParent().getParent());
    }
}

在这里插入图片描述

打破双亲委派模型

双亲委派的源码分析

双亲委派机制是靠ClassLoader的loadclass方法实现的

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

如何打破双亲委派(截止到java模块为止的三次打破–打破不是贬义词)

在这里插入图片描述

JVM参数总结以及优化(linux指令待学)

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值