JVM复习
JVM体系结构
梯形:所有线程共享数据区
矩形:线程隔离数据区
类加载器及双亲委派机制
双亲委派模型的工作过程为:如果一个类加载器收到了类加载的请求,它首先不会自己去尝试加载这个类,而是把这个请求委派给父类加载器去完成,每一个层次的加载器都是如此,因此所有的类加载请求都会传给顶层的启动类加载器,只有当父加载器反馈自己无法完成该加载请求(该加载器的搜索范围中没有找到对应的类)时,子加载器才会尝试自己去加载。
沙箱安全机制
沙箱机制就是将 Java 代码限定在虚拟机(JVM)特定的运行范围中,并且严格限制代码对本地系统资源访问,通过这样的措施来保证对代码的有效隔离,防止对本地系统造成破坏。沙箱主要限制系统资源访问,那系统资源包括什么?——CPU、内存、文件系统、网络。
栈
栈:先进后出
队列:FIFO(first in first out)先进先出
局部变量:
局部变量表就是用来存储方法中的局部变量(包括在方法中声明的非静态变量以及函数形参);若变量是基本数据类型则直接存储它的值,若变量是引用类型则存储的是指向对象的引用;而局部变量表的大小在编译的时候就已经确定了,So程序执行期间其大小亦是不会改变的。
操作数栈:
操作数栈就是用于对表达式求值计算的,当个线程执行过程实际上就是不断执行语句的过程,也就是不断计算的过程,So程序中的所有计算过程都是通过操作数栈来完成的。
指向运行时常量池的引用:
指向运行时常量池的引用是由于在方法的执行过程中有可能需要用到类中的常量,因此必须要有一个引用指向运行时常量。
方法返回地址:
一个方法执行完毕后,要返回之前调用它的位置,于是在栈中就必须保存一个方法返回的地址。
Java栈的生命周期和线程相似;在每个方法执行的同时都会创建一个栈帧,用于存储局部变量表、操作数栈、指向运行时常量池的引用和返回地址(方法出口)等信息,每个方法从调用到执行完毕的过程都对应着一个栈帧JVM中入栈到出栈到过程。(栈的大小与具体虚拟机的实现有关,一般在256~756之间)
栈的特性:
a. 生命周期与线程相似且线程属于私有;
b. 当线程请求的栈深度超过了JVM所允许的最大深度就会发生StackOverflowError异常;
c. 若是栈的扩展无法申请到足够的内存则会产生OutOfMemmoryError异常;
NATIVE关键字
Java的作用范围无法达到。
JNI是Java Native Interface的缩写,通过使用 Java本地接口书写程序,可以确保代码在不同的平台上方便移植。它允许Java代码和其他语言写的代码进行交互。通常会丧失平台可移植性。
方法区
static,final,Class,常量池
常量池
内存溢出OOM
内存溢出(Out Of Memory,简称OOM)是指应用系统中存在无法回收的内存或使用的内存过多,最终使得程序运行要用到的内存大于能提供的最大内存。
解决方式
1.尝试扩大堆内存去查看内存结果
-Xms1024m -Xmx1024m -XX:+PrintGCDetails
2.若不行,分析内存,看一下是哪个地方出现了问题(专业工具)
能够看到代码第几行出错:内存快照分析工具,MAT(eclipse),Jprofiler
Dubug,一行行分析代码!(不现实)
MAT,Jprofiler作用:
分析Dump内存文件,快速定位内存泄漏
获得堆中的数据
获得大的对象
…
GC算法
引用计数法
哪个对象的引用数为0,就会回收哪个对象
复制算法
一般新生代(伊甸园区、幸存区)会使用复制算法,生成新的to区
好处:没有内存的碎片
坏处:浪费了内存空间,多了一半空间永远是空to
复制算法最佳使用场景:对象存活度较低的时候,也就是新生区
标记清除
缺点:两次扫描,严重浪费时间,会产生内存碎片
优点:不需要额外的空间
标记压缩
对于标记清除的再压缩
标记清除压缩
先标记清除一次,然后再压缩
总结
内存效率:复制算法 > 标记清除算法 > 标记压缩算法(时间复杂度)
内存整齐度:复制算法 = 标记压缩算法 > 标记清除算法
内存利用率:标记压缩算法 = 标记清除算法 > 复制算法
思考:难道没有最优算法吗?
答案:没有,没有最好的算法,只有最合适的——>GC:分代收集算法
年轻代:
存活率低
复制算法
老年代:
区域大,存活率高
标记清除(内存碎片不是太多) + 标记压缩混合实现
还是要多看书《深入理解JVM》,花时间去深究,多看面试题。
优化GC步骤
1.首先需要观察目前垃圾回收的情况,分析出老年代和年轻代回收的情况,适当的去调整内存大小和-XX:SurvivorRatio的比例。
2,。根据垃圾收集器的特性,选择适合自己业务的垃圾收集器,一般来说现在的WEB服务都是CMS+ParNew收集器。根据CMS收集器一般来说就会产生大量碎片,根据自己的需求悬着相应的压缩频率即可。
3.不断的调整jvm内存比例,老年代、年轻代、以及持久代的比例,直到测试出一个比较满意的值。
JMM
什么是JMM?
JMM:Java Memory Model的缩写
它干嘛的?
作用:缓存一致性协议,用于定义数据读写的规则。
JMM定义了线程工作内存和主内存之间的抽象关系,线程之间的共享内存存储在主内存(Main Memory)中,每个线程都有一个私有的本地内存(Local Memory)
JVM常用参数
该如何学习?
什么是***?
干嘛的?
怎么学习?