jvm的一点理解

整体把握,学习jvm

【几个问题】

1.什么是jvm?

jvm是虚拟机,模拟物理机使之能够执行java代码,既然是模拟物理机,那么也是模仿冯诺依曼体系结构,有输入数据,然后经过控制器运算器存储器等处理,最后输出。
jvm将class文件作为输入,经过中间虚拟机的处理翻译,最后由虚拟机的引擎执行。

2.java为何能跨平台

是因为jvm能够执行java代码。我们下载的jdk包含了jvm,jdk就有Windows版,linux版,mac版,不同的版本适应了不同的平台,自然java就能跨平台运行。

1.jvm的体系结构

Hotbot虚拟机体系结构


主要分为如下几个部分

1.ClassLoader加载器
3.运行时数据区
4.本地方法栈
5.垃圾收集器
6.JIT即时编译器(字节码translate cpu指令)
7.执行引擎

1.ClassLoader加载机制

java文件通过javac命令编译成文字节码文件,再将class文件装载进虚拟机,由虚拟机处理执行。

1.class文件加载方式

装载方式:隐式加载和显式加载。

隐式加载:虚拟机自动加载clas文件到内存。

显示加载:通过代码ClassLoader加载    
具体的代码方式:
class.forName,ClassLoader.findClass()

this.getClass.ClassLoader.loadClass()。

2.加载Class文件到内存的步骤

1.先加载class文件到内存(路径)
URLClassLoader 以URL数组传参方式加载URL路径下的类字节码文件到jvm中。

2.字节码验证
验证字节码的文件结构格式之类的。

3.初始化对象赋值  静态初始化

3.jvm加载前对类的检测

jvm加载类进入虚拟机的时候,会先检测虚拟机中是否存在相同的类,以防止重复加载。

判断是否是相同类的标准:
1.判定类的名称,所存在的包 是否相同
2.判断是否由同一个ClassLoader实例对象加载进来的。

就算是相同的类(名称啊,所在的包相同),只要加载的ClassLoader实例对象不同,也会被虚拟机认为是不同的类,那么依然会选择加载进来。因此我们就可以实现重复加载相同的类进入虚拟机了,我们开发中使用的热部署就是这样实现的。

2.运行时数据区

由ClassLoader加载进来的数据是如何在jvm中分配的呢?运行时数据区就是分配了不同的区域来存储不同的数据。

1.jvm内存模型区域划分

运行时数据区划分了

  • 堆区
  • java虚拟机栈
  • 方法区
  • 本地方法栈
  • 程序计数器

【堆区与方法区】

堆内存是共享的,内存比较大,存的是大内存数据。
类的实例和数组都会放到这里。

方法区存放  方法的数据 类的结构构造函数模板  运行时常量池

【java虚拟机栈】

java虚拟机栈内存放在一个线程中的,存放基本数据类型,局部变量和对象的引用(句柄)。 数据不共享。
程序计数器记录的是线程执行的方法的位置。 
本地方法栈 存放的是C语言,c++方法,当java虚拟机栈执行本地方法的时候,动态链接本地方法栈从而实现运行。

java虚拟机栈
2.内存的分配策略

对象优先在Eden上分配,Eden区域没有足够的区间,会进行一次Minor GC;如果还没有,会在老年代分配。

一次Major GC至少会有一次Minor GC.Major GC速度慢。

大对象(大量连续内存空间的对象)直接在老年代分配,老年代空间大。

长期存活的对象进入老年代,

动态对象判定。不会一致根据某个固定的值判定年龄。
若在 Survivor 区中相同年龄所有对象大小的总和大于 Survivor 空间的一半,年龄大于等于该年龄的对象就可以直接进入老年代。

空间分配担保
在新生代触发 Minor GC 后,如果 Survivor 中任然有大量的对象存活就需要老年队来进行分配担保,让 Survivor 区中无法容纳的对象直接进入到老年代。

3.java内存模型

java的内存模型与jvm的内存模型无关,但可以类比。
java内存模型:主内存(类比jvm堆区和方法区)+工作内存(类比jvm栈 本地方法 )

java线程从主内存中拷贝数据到各自的工作内存,数据处理之后不定时写回主内存。

3.垃圾回收器
  • 垃圾回收算法
  • 判断垃圾
  • 什么时候回收
  • 如何回收
  • gc调优

【GC垃圾回收算法】

1.标记-清除算法

两个阶段: 标记+回收

有点:简单不需要移动对象
缺点: 造成大量内存碎片 效率不高。

2.复制算法

优点:解决了标记清除的效率问题,将内存分两块,遍历当前内存将存活的对象复制放到另一块内存,最后清除这块内存的对象。。。

3.标记整理算法

优点:解决内存碎片问题 将存活的对象压缩到内存一端,可回收的就是另一边。
缺点: 需要移动一些对象 效率低一点

4.分代收集算法

将对象分代存放回收。
根据 对象的生存周期 分了几块内存,新生代,老年代,永久代。

大部分对象创建放在新生代,一个叫Eden区域,直到对象不可达,会被回收。这个阶段被回收称为minor GC。

新生代没有不可达,并且幸存下来的,会被放到老年代,空间较大,GC次数少,这个阶段被回收的成为full GC 或者major GC

永久代  存放的是一些类的层级信息,方法数据,方法信息等。jdk8之后取消了,将数据放到了b本地内存区域。

6.什么时候回收

当对象不再被引用,就会被回收。
1.引用计数法
当引用次数=0就会被回收。
引用分为 强引用 弱引用 软引用  虚引用  

new 的方式 就是强引用 不会被垃圾回收    

软引用就是 非必须的对象 如果本次垃圾回收之后还是内存不足 还是会回收。SoftReference实现。

弱引用 比软引用更弱一些。无论内存是否不足,都会被回收。WeakReference实现。

虚引用时最弱的一种引用。作用是被垃圾回收的时候有系统通知。

7.其他的垃圾收集器

4.JIT编译器和执行引擎


java字节码由执行引擎执行的,
JIT是将java字节码编译成本地机器能识别的机器指令,
现在的虚拟机采用半编译半解释。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值