JDK官网:Home: Java Platform, Standard Edition (Java SE) 8 Release 8
JVM有两种模式 Client模式和server模式
client模式使用的是轻量级的编译器,server模式使用的是重量级的编译器,server模式下编译器在编译的时候相对而言更加的彻底,服务启动之后性能更高,但是启动的时候比较耗时,速度较慢;
在JDK安装完成之后,输入命令Java -version 就可以查看信息:(默认mixed mode混合模式--由jdk自己进行选择,通常是server模式)
➜ / java -version java version "1.8.0_202" Java(TM) SE Runtime Environment (build 1.8.0_202-b08) Java HotSpot(TM) 64-Bit Server VM (build 25.202-b08, mixed mode) ➜ / java -Xmixed -version java version "1.8.0_202" Java(TM) SE Runtime Environment (build 1.8.0_202-b08) Java HotSpot(TM) 64-Bit Server VM (build 25.202-b08, mixed mode) ➜ / java -Xint -version java version "1.8.0_202" Java(TM) SE Runtime Environment (build 1.8.0_202-b08) Java HotSpot(TM) 64-Bit Server VM (build 25.202-b08, interpreted mode) ➜ / java -Xcomp -version java version "1.8.0_202" Java(TM) SE Runtime Environment (build 1.8.0_202-b08) Java HotSpot(TM) 64-Bit Server VM (build 25.202-b08, compiled mode)
Java文件在进行编译之后生成class文件,经过类加载机制,将class文件装载到JVM对应的内存区域
编译过程:
Java文件 ----> 词法分析 ----> tokens流 ---->语法分析器 ----> 语法树/抽象语法树 ----> 语义分析器 ----> 注解抽象语法树 ----> 字节码生成器 ----> class文件
1、Java虚拟机运行时数据区
2、 Java对象内存布局
分为三部分:对象头,实例数据,对齐填充(8字节的整数倍)
3、如何判断对象”已死“?
分析方式:
引用计数法:对象每被引用一次就将计数器加一;弊端:无法解决对象之间的循环引用;
可达性分析算法:通过一系列的“GC Root”对象,以它为起点,向下搜索,它走过的路径成为引用链,如果一个对象到GC Root没有任何引用链,那么该对象就是不可达,就判定为可回收对象;
可回收对象并非为必须回收,它至少要经过两次标记过程,第一次就是可达性分析中的标记,检查是否需要执行finalize()方法,如果没有覆盖或者已经被虚拟机调用过的就是没有必要执行,否则就是有必要执行;第二次标记,有必要执行就将该对象存到一个F-Queue队列中,虚拟机会创建一个低优先级的Finalize线程执行;在finalize()方法中是对象最后一次逃脱被回收的机会,finalize()方法只会被执行一次,如果在该方法中,对象被GC Root对象或者调用链中的任何一个对象引用,就成功逃脱被回收;这种方式是不被推荐使用的;
可以作为GC Root的对象有:
a、虚拟机栈(栈帧中的本地变量表)中引用的对象;
b、方法区中的类静态属性引用的对象
c、方法区中常量引用的对象
d、本地方法栈中JNI引用的对象
示意图如下:
引用分类:
强引用:例如:Object obj = new Object();这类引用还存在,垃圾收集器就永远不会回收这类被引用的对象
软引用:可以通过SoftReference类来实现软引用;
A a = new A(); SoftReference sr = new SoftReference(a); sr.get();
软引用关联的对象,在系统将要发生内存溢出异常之前,将会把这些引用对象列入回收范围之内进行第二次回收,如果这次回收还没有足够的内存就会抛出内存溢出异常;
弱引用:可以通过WeakReference类来实现;被软引用关联的对象只能生存到下一次垃圾回收发生之前,无论内存是否足够;
虚引用:可以通过PhantomReference类来实现;设置一个虚引用的目的就是能在收集器回收时受到一个系统通知;
3、垃圾收集器与内存分配策略
垃圾收集算法:标记清除(效率低,产生的不连续空间碎片多)、复制算法(实现简单,运行高效,空间浪费--后续有改进8:1:1)、标记整理(综合了标记清除和复制算法)
复制算法常用在新生代,标记整理算法常用在老年代
分代垃圾收集器:
垃圾收集算法的升级就是在优化缩短用户线程的停顿事件(Stop the world)
Serial 收集器:单线程收集器,不仅仅说明使用一个CPU或者一条收集线程去完成垃圾收集工作;更重要的是在垃圾收集过程中需要暂停其他所有的工作线程,直到结束收集工作(stop the world);
图片引用:https://gimg2.baidu.com/image_search/src=http://www.kaotop.com/skin/sinaskin/image/nopic.gif>
在垃圾收集器的上下文语境中,并发和并行的解释如下:
并行:多条垃圾收集线程并行工作,但此时用户线程仍然处于等待状态
并发:用户线程和垃圾收集线程同时执行,用户程序继续执行,垃圾收集程序在另一个CPU上执行;
对象内存分配:
对象优先在Eden分配,若Eden没有足够的空间就进行一次Minor GC;
大对象直接进入老年代
长期存活的对象进入老年代
4、常用的虚拟机性能监控和故障处理工具
jstat 可以监测 Java 应用程序的实时运行情况,包括堆内存信息以及垃圾回收信息
下一章节: 调优案例分析
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)