简单初识JVM
JavaDevelopmentKit(JDK)是一款Java语言的软件开发工具包
Java运行环境(Java Runtime Environment,简称JRE),JRE的内部有一个Java虚拟机(Java Virtual Machine,JVM)以及一些标准的函数库lib(Class Library)。
JVM 主要分为有:方法区(JDK1.8及以后改为元空间),堆,栈,程序计数器,本地方法栈。
程序计数器:是线程私有的,它会记住jvm指令的执行地址的作用,多线程切换的时候可以有条理的进行下一条指令。
方法区:存静态变量、常量、类信息(构造方法、接口定义),运行时常量池存在方法区中,但是实例变量存在堆内存中与方法区无关。(static,final,常量池)
关于栈:
栈是线程级别,线程结束了内存就释放,不存在垃圾回收的问题。
堆是只有一个。栈它是先进后出。
主要存:8种基本类型+对象引用地址+实例的方法。
关于堆:主要存区对象实例,数组
关于native(在内存中开辟了native本地方法栈):
凡是带了native关键字的,说明java的作用范围达不到,就会调用底层的C语言库
会进入本地方法栈(JNI)
调用本地方法接口
JIN作用:扩展Java的使用,融合不同的编程语言为JAVA所用,去调用其他语言的程序。
它在内存区域中专门开辟了一块标记区域:Native Method Stack,登记Native方法。
在最终执行的时候,通过JIN加载本地方法库中的方法
GC作用区域:方法区、堆。
JVM的双亲委派机制:
APP(应用)-EXT(扩展)-ROOT(根)。
就是向上委派,向下加载,子类都会向上传递,不会去加载,到ROOT
如果ROOT加载不了,ROOT就会向下传递给子类加载。
下面我们讲的都是关于:HotSpot JVM
目前只有三种JVM:
Sun公司:HotSpot
BEA JRockit
IBM J9 VM
如何发现内存OOM问题:可以在IDEA安装插件JProfiler插件,同时安装客户端;
垃圾回收的算法:
JVM在进行GC时并不是都对新生代、幸存区(from,to)、老年区这三个区域统一回收,回收都是新生代
GC两种类型:
轻GC(普通的GC):新生代、幸存区(from,to)
重GC(全局GC):新生代、幸存区(from,to)、老年区
幸存区(from,to):谁空谁是to,
每一次GC都会将Eden(年轻代)活的对象移到幸存区:一旦Eden区被GC后,就是会空的。
当一个对象经历15次GC后还活着的就会送入老年区。
JVM调优也可以自己设置GC -XX:MaxTenuringThreshold=5,经历五次就可以进入老年区,最大只能设置成15 只有四位1111==15。
复制算法:
优点:没有内存的碎片
坏处:浪费了内存空间:多了一半空间是空to。假设对象100%存活(极端情况)
该算法最佳使用场景:对象存活较低的时候;列如新生区(Eden--幸存区to--幸存区from);
标记压缩清楚法:一共三步(需扫描三次)
标记清除法:
第一次扫描:扫描这些对象,对存活的对象进行标记。
第二次扫描:对整个空间内没有标记的对象,进行回收。
优点:不需要额外的空间
缺点:两次扫描,严重浪费时间,会产生内存碎片。
标记压缩:防止内存碎片产生,再次扫描,向一端移动存活的对象,多了一次移动成本。
再进行压缩。
总结:
内存效率:复制算法>标记清除法>标记压缩算法(时间复杂度)
内存整齐率:复制算法=标记压缩算法>标记清除法
内存利用率:标记压缩算法=标记清除算法>复制算法
考虑新的调优算法:
分代收集算法:
年轻代:存活率低,复制算法。
老年代:区域大:存活率高 。标记清除+标记压缩混合实现(标记多少次再执行压缩?需看实际情况)
引用技术法:对象被引用了技术器+1,引用结束-1,计数器为0就会被回收。
可达性分析法: 这个算法的基本思想就是通过⼀系列的称为 “GC Roots” 的对象作为起点,从这些节点开始向下 搜索,节点所⾛过的路径称为引⽤链,当⼀个对象到 GC Roots 没有任何引⽤链相连的话,则证明此对象是不可⽤的,则需要清除对象进行内存回收。
引用技术法与根搜索法(可达性分析法)是用来判断对象是否是废弃(活)对象。
未完.。。。待续