内容简介:从上面的图可以看到,包含Class文件,类加载器(classloader),内存空间(分为方法区,java堆区,java栈区,本地方法区,垃圾收集),执行引擎,本地方法接口。
JVM的结构
从上面的图可以看到,包含Class文件,类加载器(classloader),内存空间(分为方法区,java堆区,java栈区,本地方法区,垃圾收集),执行引擎,本地方法接口。
- class文件 就是 java 文件编译生成的
- ClassLoader 是加载.class文件的加载器
- 方法区 是用来存储被加载的类信息,常量,静态常量,静态方法等,(永远占据内存)。常量池在方法区内,收到方法区的限制,当常量池无法申请到内存的时候就会抛出OutOfMemoryError异常
- 堆区 是存放所有new出来的对象,是java虚拟机所管理的内存中最大的一块,被所有的线程共享,也是GC管理的主要区域
- java栈区 每个方法被调用的时候都会创建一个栈帧,用来存储局部变量,操作栈,动态链接,方法出口灯信息。当线程请求的栈深度大于虚拟机所允许的深度的时候会抛出StackOverflowError。当栈的扩展无法申请到足够内存的时候会抛出OutOfMemoryError异常
- 本地方法区 主要为native方法服务,线程隔离,跟java虚拟机栈类似。区别就是java虚拟机栈是用来执行java服务的,而本地方法栈是为执行native方法服务的
- 程序计数器 是线程隔离区域,每个线程都有自己的程序计数器,存储当前执行的字节码的行号,保证线程切换后能恢复到原来的执行位置。
Java代码的编译和执行过程
编译:
Java源代码是不能被机器识别的,需要经过编译器变异成JVM虚拟机可执行的.class字节码文件,在由解释器解释运行。把.java文件编译成.class文件。上面图其实就是javac命令根据不同的解析语法来解析java文件。
加载:
使用Classloader或者它的子类加载编译好的文件,Java中主要包含下面几中加载器
Bootstrap ClassLoader: 根ClassLoader,用C++实现,专门用来加载Java的核心API:$JAVA_HOME中jre/lib/rt.jar中所有class文件rt的意思是runtime
Extension ClassLoader: 加载Java扩展API jre/lib/ext中的类
App ClassLoader: 加载classpath目录下定义的class,也就是应用程序用到的ClassLoader。
Custom ClassLoader: 可以自定义的ClassLoader,可以继承这个ClassLoader然后自己实现。
类的加载过程如下
加载:把.class类的信息从文件中获取并且载入到JVM内存里
验证:检查读入的字节码是否符合JVM规范
准备:分配一个数据结构来存储类的信息,为静态变量分配内存,将其初始化为默认值。
解析:把这个类的常量池中的所有的符号引用改变成直接引用
初始化:执行静态初始化程序,把静态变量初始化成指定的值
执行:
JVM执行引擎执行字节码
垃圾回收
垃圾回收主要针对堆内存部分,按照分代算法划分,堆内存空间可以分为年轻代和老年代。
年轻代和老年代是根据对象的存活周期的不同划分的,年轻代短,老年代长。
刚创建的对象会放到年轻代,年轻代的对象一般会在下一次垃圾回收的时候被回收,多次GC都没有被回收的对象就进入到了老年代
我们可以根据业务动态的调整年轻代和老年代的区域的大小。
垃圾收集算法找出哪些是垃圾
引用计数算法:
给每个对象分配一个引用计数器,每当有地方引用该对象的时候,引用计数器的值加一,当引用失效的时候,引用计数器减一,如果引用计数器为0说明该对象不在被引用了
缺点:如果两个对象之间互相引用,比如A引用B,B引用A,别的对象都没有引用A或者B,这时候他们俩其实是垃圾了,但是他们的引用计数器不为0,计数器也就无法通知GC回收他俩了。
可达性算法(java1.2之后):
通过一些被称为引用链(GC Roots)的对象作为起点,从这些节点开始往下搜索,搜索走过的路程叫做引用链(Reference Chain),如果一个对象到GC Roots没有任何引用链接,说明这个对象不可用了。
Java中可以被称为GC Root的对象可以是一下几种:
(1)虚拟机栈(栈帧中的本地变量表)中引用的对象
(2)方法区中静态属性引用的对象
(3)方法区中常量引用的对象
(4)本地方法中Native方法引用的对象
上面两种算法中都有引用这个概念,Java中的引用有四种
(1)强引用,new出来的对象比如Object obj = new Object()的引用。垃圾回收器永远不会收集被强引用的对象。
(2)软引用,一些有用但不是必须的对象Java中使用java.lang.ref.SoftReference来表示,在内存不足的时候会回收改对象
(3)弱引用,非必须对象,当垃圾回收的时候无论内存是否充足,都会回收被弱引用挂你蓝的对象,Java中使用java.lang.ref.WeakReference这个类来表示
(4)虚引用,任何时候都可以被回收,Java中使用java.lang.ref.PhantomReference类表示。用的不多。
垃圾回收算法回收垃圾
1.标记清除算法
图片是从网上寻找的
从根节点开始遍历所有的引用,未被引用的对象标记为可回收对象,清除可回收对象
优点:不需要对象的移动,直接删除未被引用的对象,在对象较少的时候效率高
缺点:由于直接删除对象,会造成内存碎片
2.复制算法
图片是从网上寻找的
找一块空闲内存,从根节点开始遍历,把可以引用的对象复制到新的内存块中,然后清除原来内存块中的所有对象
优点:不会出现内存碎片
缺点:需要一块内存作为交换空间来移动对象,空间成本较高
3.标记整理算法
图片是从网上寻找的
从根节点开始遍历标记有引用的对象,未被标记的就是需要回收的,删除掉需要回收的对象之后,把所有对象压缩到内存的一端
优点:不会产生内存碎片
缺点:需要进行对象的移动,时间成本较高。
触发回收
- Java虚拟机无法为新的对象分配内存空间了
- 手动调用System.gc()方法(不推荐)
- 低优先级的GC线程被运行时会执行GC
Dalvik VM 和 JVM的区别
- 执行文件不同,一个是class,一个是dex
- 类加载的系统与JVM区别较大
- 可以同时存在多个Dalvik VM
- Dalvik是基于寄存器的,而JVM是基于栈的
Dalvik VM 和 ART的区别
- DVM使用JIT来将字节码转换成机器码,每次都要重新加载,效率低。
- ART使用AOT的预编译技术,当应用安装的时候,就把字节码转换成机器码。
- ART会占用更多的应用安装时间和存储空间,以空间换时间。
以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网
猜你喜欢:- 【1】JavaScript 基础深入——数据类型深入理解与总结
- 深入理解java虚拟机(1) -- 理解HotSpot内存区域
- 深入理解 HTTPS
- 深入理解 HTTPS
- 深入理解 SecurityConfigurer
- 深入理解 HTTP 协议
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。