虚拟机讲解

一.java虚拟机结构解析。

1.JVM整体结构组成。

虚拟机讲解_第1张图片
211701570812376.jpg

上图就是JVM整体结构图,主要分为几个模块:
class 文件生成模块:javac命令。
类加载器子系统:将class字节码加载到jvm对应的虚拟机内存中(核心就是ClassLoader),如下图。
虚拟机讲解_第2张图片
80a46038ad7f148edef4bd2116d2ed21.png

加载流程:
虚拟机讲解_第3张图片
u=1093279780,2275276243&fm=27&gp=0.jpg

a.加载过程:类的信息从文件中获取并且载入到虚拟机内存中。
b.验证过程:检查读入的结构是否符合JVM规范的描述。
c.准备过程:分配一个结构用来存储类信息。
d.解析过程:把这个类的常量池中的所有的符号引用改变为直接引用。
e.初始化过程:执行静态初始化程序,把静态变量初始化为指定的值。
内存空间:分为方法区,堆区,栈区,本地方法栈。
a.Java栈区:
作用:它存放的时Java方法执行时的所有的数据。
组成:由栈帧组成,一个栈帧代表一个方法的执行。
栈帧的作用:每个方法从调用到执行完成就对应一个栈帧在虚拟机栈中入栈到出
栈。
栈帧的组成:局部变量表、栈操作数、动态链接、方法出口。
b.本地方法栈:
作用:专门为Native方法服务的,其他和Java栈区一样。
c.方法区:
作用:存储被虚拟机加载的类信息、常量、静态变量、即时编译器编译后等数
据,方法区时是永远占据内存的。
d.Java堆区:
作用:所有通过new创建的对象的内存都在堆中分配。
特点:是虚拟机中最大的一块内存,是GC要回收的部分。
堆区内存结构如下图
虚拟机讲解_第4张图片
711d886e93e98896da404492547382b6.jpg

Young Generation 新生代:新创建的对象会放到新生代区。
Old Generation 老生代:当新生代内存不足时,jvm虚拟机会通过一定的算法将新生代区的对象移到老生代区中,当老生代和新生代都没有足够的内存时就会抛出oom异常。
jvm为什么要将堆区这块内存分为新生代和老生代呢,为什么不是一块内存?
可以让开发人员去动态的调整Young Generation区域的大小和Old Generation区域的大小,比如说我们在做一些即时通讯应用的java服务器的时候,可能创建一些message对象这种临时消息比较多,我们可以将新生代内存区域调整的大一些,老生代内存区域调整的小一些,这样便于我们的内存分配,也可以加快对象的创建,而我们要开发大型服务类程序的话,可能不需要频繁创建对象,这时候我们就可以适当减少新生代的内存区域,增加老生代内存区,达到对象常驻内存效果。
垃圾收集器:所谓的gc。
3.如何确定某个对象是垃圾。
a.引用计数算法:我们在内存中创建一个对象的时候,同时为它产生一个引用计
数器,同时将引用计数器加1,每当有新的引用引用到此对象的时候,引用计数
器就累计加1,而当其中的一个引用销毁的时候,引用计数器就减1,当引用计
数器减为0的时候,标志着对象已经是垃圾对象了,可以被垃圾回收器回收。
缺陷:循环引用。
b.可达性分析:将所有的引用关系看作一个图,从gcroot节点开始寻找所有对应
的引用节点,找到节点以后继续寻找该节点的引用,当所有的引用节点寻找完毕
之后,剩余的节点则被认为是没有被引用的节点,即不可达的节点,即垃圾对
象,避免了循环引用。如图
虚拟机讲解_第5张图片
52b0817a68a45313cf0eb4ce9fdbebd8.jpg

4.引用类型
强引用、弱引用、软引用、虚引用,常用的是强引用和弱引用。
弱引用的创建:

   Object obj = new Object();
   WeakReference wf = new WeakReference(obj);
    obj = null;
    wf.get();

首先创建一个强引用obj,然后创建object的弱引用wf,所已我们的Object对象有两个引用指向了它,一个是obj,一个是wf,我们把obj置为null,所以只有wf指向了Object对象,wf.get()时要判断获取的引用是否为null,因为弱引用是不会阻碍垃圾回收。
5.垃圾回收算法
a.标记-清除算法:如图

虚拟机讲解_第6张图片
596ea6675514117f8998839de57d4013.jpeg

首先从根集合即根节点来遍历所有的引用,可以路由到A对象的引用,由A对象
可以路由到C对象的引用,而B对象成为不可达的引用,B就会被标记成可回收对
象。
好处:不需要进行对象的移动,并且仅对不存活的对象进行处理,在存活对象多
的情况下极为高效。
缺点:因为标记清除算法会直接清除不存活的对象,因此会造成内存碎片
b.复制算法:如图
虚拟机讲解_第7张图片
5dbb48c91f32d71046e6aaf5b12501f2.jpg

也是从根节点开始遍历,遍历到A引用是可达的,那么就会把A引用复制到另一
块空闲的内存,B引用是不可达的,它就直接跳过不去复制,C是可达的,直接
复制到空闲内存中,遍历完后会把原来的内存空间清空。
优势:当存活的对象比较少时极为高效 。
缺点:需要一块内存空间来做交换移动。
c.标记-整理算法:如图
虚拟机讲解_第8张图片
6e4af306dc6d24ed61a30174fab73040.jpg

首先也是从根集合开始遍历,通过对内存区的扫描,会把可回收的内存扫描出来,从图中可以看出,第二阶段B内存已经被扫描出来了,第三阶段扫描整个内存空间并清除可回收对象,标记-整理算法是在标记-清除算法上做了改进,在回收不存活对象占用的空间的时候,会将所有存活对象向左空闲空间处移动,并更新对应的指针,相比较标记-清除算法成本更高,却解决了内存碎片问题。
这三种算法各有优劣,是在我们虚拟机中结合使用的。
6.触发回收
a.Java虚拟机无法再为新的对象分配内存空间了。
b.手动调用System.gc()方法(不推荐 )
c.低优先级的GC线程被运行时就会执行GC。

二.Dalvik与JVM的不同。

1.执行的文件不同,一个是class,一个是dex。
2.类加载系统不同。
3.JVM只可以存在一个,Dalvik可以存在多个(好处:某个应用的虚拟机挂掉之后
不会影响其他应用的运行)。
4.Dalvik是基于寄存器(更快 )的,JVM是基于栈的。

三.ART比Dalvik有哪些优势。

1.Dalvik使用JIT来将字节码转换为机器码,效率低,JIT技术就是应用每次运行的
时候 都会将字节码转化为本地机器码,再去执行,一旦退出应用再次进入时,就
要重新转化 ,效率低。
2.ART采用了AOT预编译技术,执行速度更快。AOT就是在我们应用程序安装的
时候就将我们的字节码转换成了本地机器码 ,保存在存储介质中,这样应用程序
不管何时启动,都是执行的本地机器码 ,不需要每次都转换 ,但是ART会占用
更多的应用安装时间和存储空间(用空间换时间)。

你可能感兴趣的:(虚拟机讲解)