Java学习-JVM狂神笔记

目录

JVM是什么,JVM的体系结构

类加载器

双亲委派机制

沙箱安全机制

虚拟机运行时数据区

Native

PC寄存器

方法区Method Area

栈heap

         GC垃圾回收

引用计数法

复制算法

 标记清除算法



JVM是什么,JVM的体系结构

Java平台可分为两部分,即Java虚拟机和java API类库

JVM是Java Virtual Machine的缩写,JVM是一种用于计算机设备的规范,它是一个虚构出来的计算机,是通过在实际的计算机上仿真模拟各种计算机功能来实现的。

Java虚拟机主要分为五大模块:类装载器子系统、运行时数据区、执行引擎、本地方法接口和垃圾收集模块

JVM整体认知图

JDK是Java程序员常用的开发包,目的就是用来编译和调试JAVA程序的

JRE是指Java运行环境,写好的程序必须在JRE才能够运行

JVM是Java虚拟机的缩写,是指负责将字节码解析成为特定的机器码进行运行,值得注意的是在运行过程中,Java源程序需要通过编译器编译为.class文件。

类加载器

加载class文件

对象变回class

双亲委派机制

当一个.class文件被加载时

结论: AppClassLoder–>Ext–>Boot(最终执行)

应用程序加载器,扩展类加载器,根加载器,虚拟机自带的加载器

类加载器收到请求

将请求向上委托给父类加载器去完成,一直向上委托,直到启动自动类加载器

启动加载器检查是否能够加载当前这个类。能加载就结束,使用当前的加载器,否则抛出异常,通知子加载器进行加载

双亲委派机制的作用

防止重复加载同一个.class。通过委托去向上问一句加载过了,就不用在加载一遍了。保证数据安全

保证核心.class不能被篡改。通过委托方式,不会去篡改核心.class,即使篡改也不会去加载,即使加载也不会是同一个.class对象。不同加载器加载同一个.class也不是同一个class对象。这样保证了Class执行安全。

沙箱安全机制

组成沙箱的基本组件

字节校验器:确保Java类文件遵循JAVA语言规范。这样可以帮助Java程序实内存保护。但并不是所有的类文件都会经过字节码校验,比如核心类

类加载器:其中类加载器在三个方面对java沙箱起作用

它防止恶意软件代码去干涉善意代码;

守护被信任的类库边界

将代码归入保护域,确定了代码可以进行哪些操作

存取控制器:存取控制器可以控制核心API对操作系统的存取权限。而这个控制的策略设定,可以由用户指定。

安全管理器:是API和操作系统之间的主要接口。实现权限控制,比存取孔子器优先级高。

安全软件包:java.security下的类和扩招包下的类,允许用户为自己的应用增加新的安全特性,包含:安全提供者  消息摘要  数字签名 加密 鉴别

虚拟机运行时数据区

Native

方式带有native关键字的,说明Java的作用范围已经达不到了,会去调用底层c语言的库,会进入本地方法栈 ,调用本地方法接口JNI。JIN作用:扩展Java的使用,融合不同编程语言Java所用。Java诞生的时候C、C++盛行,想要立足,必须要有调用C、C++的程序,它在内存区域中专门准别了一块标记区域:Native Method Stack,登记native 方法。最终执行的时候,加载本地方法库中的方法通过JNI.

PC寄存器

程序计数器:program counter register

每个线程都有一个程序计数器,是线程私有的,就是一个指针,指针指向方法区中的方法字节码(用来存储指向一条指令的地址,也即将要执行的指令代码),在执行引擎读取下一条指令,是一个非常小的内存空间,几乎可以忽略不计。

方法区Method Area

方法区是被所有线程共享,所有字段和方法字节码,以及一些特殊方法,如构造函数,接口代码也在此定义,简单来说,所有定义的方法信息都存在该区域,此区域属于共享区间;静态变量、常量、类信息(构造方法、接口定义),运行时的常量池存在方法区中,但是实例变量存在对内存中,和方法区无关。

栈heap

栈内存,主管程序的运行,生命周期和线程同步;线程结束,栈内存也就是释放,对于栈来说,不存在垃圾回收问题,一旦线程结束,栈就over。栈内存中存在:8大基本类型+对象引用+实例的方法

栈运行的原理:栈帧

栈满:StackOverflowError

栈帧图解:栈底部子帧指向上一个栈的方法,上一个栈的父帧指向栈底部方法

三种JVM:Sun公司HotSpot Java Hotspot™ 64-Bit Server VM (build 25.181-b13,mixed mode) ●BEA JRockit ●IBM J9VM 我们学习都是: Hotspot

一个JVM只有一个堆内存,堆内存的大小是可以调节的;类加载器读取文件后

方法区:存放类、方法、常量及变量

堆中:保存我们所有引用类型的真实对象(对象实例

堆内存还要细分为三个区:新生区(伊甸园去),

  • 伊甸园Eden、辛存区from及辛存区to(from–>to 动态交替的)

老年区,永久区

新生区:

新生区诞生和成长的地方,甚至是死亡

伊甸园:所有的对象都是在伊甸园创建new出来的

老年区:

当伊甸园存满且经过GC(垃圾回收区)后,没有被GC回收的对象存幸存区

当第一步把幸存区存满后对象将反放入老年区

说明:经过研究验证:99%的对象都是临时对象;说明大部分对象在伊甸园区被回收

永久区:

这个区域常驻内存,用来存在JDK自身携带的Class对象、interface元数据、存储的是java运行的一些环境或类信息,这个区域不存在来不及回收。关闭虚拟机就会释放这个区域的内存

出现OOM(内存溢出)的情况:

一个启动类加载了大量的第三方jar包,Tomcat部署了太多的应用,大量动态生成反射类,不断地被加载器加载

jdk1.6以前:有永久区,常量池在方法区

jdk1.7:有永久区,但是慢慢退化‘去永久区’,常量池在堆中

jdk1.8及以后:无永久区,常量池在元空间

在一个项目中,突然出现了OOM故障,那么该如何排除

能够看到代码第几行出错:内存快照分析工具,MAT, Jprofiler ●Dubug, 一行行分析代码

MAT, Jprofiler作用:分析Dump内存文件,快速定位内存泄露;获得堆中的数据 ,获得大的对象~

Jprofile使用 

1.在idea中setting-plugins下下载jprofile插件 2.联网下载jprofile客户端 3.在idea中VM参数中写参数 -Xms1m -Xmx8m -XX: +HeapDumpOnOutOfMemoryError 4.运行程序后在jprofile客户端中打开找到错误告诉哪个位置报错(show in explorer)

常用参数说明:

-Xms5m:设置初始化内存分配大小5m;默认为1/64
-Xmx10m:设置最大分配内存10m;默认1/4
-XX:+PrintGCDetails :打印GC垃圾回收
-XX:+HeapDumpOnOutOfMemoryError :Dump报错信息
-XX:MaxTenuringThreshold=5 :更改辛存区到老年区的阈值

GC垃圾回收

GC的算法有哪些?标记清楚发、标记压缩、复制算法、引用计数器

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

引用计数法

给每个对象分配一个计数器,计数器本身也有消耗,所以并不高效不常用

复制算法

谁空是是to

第一次GC后,Eden区和to区空,经过15此垃圾回收后依然存活下来的对象就会去养老区

好处:没有内存的碎片

坏处:浪费内存空间(一个幸存区的空间永远是空)

复制算法最佳使用场景:对象存活度较低的时候

 标记清除算法

 优点:不需要而外的空间

缺点:两次扫描严重浪费时间,会产生时间碎片

改进:标记清除再压缩

压缩是防止内存碎片产生,再次扫描,向一端移动存活的对象多了一个移动成本

总结:

内存效率:复制算法>标记清除算法>标记压缩算法

内存整齐度:复制算法=标记压缩算法>标记清除算法

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

最合适的算法 —> GC:分代收集算法

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值