一、java旅程
萌芽前夕阶段: -1、1995年提出Oak语言,因商标已被注册,后改名为Java 萌芽阶段: 0、 1996年,正式发布1.0版本 1、 1997年,正式发布1.1版本 2、 1998年,正式发布1.2版本,java2 发芽阶段: 3、 2000年,正式发布1.3版本,java3 4、 2002年,正式发布1.4版本,java4 5、 2004年,正式发布1.5版本,java5 增长阶段: 6、 2006年12月,正式发布1.6版本,java6 7、 2011年 7月,正式发布1.7版本,java7 快速发展阶段: 8、 2014年3月18日,正式版本java8【lts】 9、 2017年9月21日,正式发布java9 10、2018年3月20日,正式发布java10 11、2018年9月25日,正式发布java11【lts】 12、2019年3月19日,正式发布java12 13、2019年9月17日,正式发布java13
二、java虚拟机架构
1、类加载系统:负责从文件系统或者网络中加载class信息,存储到方法区的内存空间。 2、方法区:除了类的信息外,方法区还存储运行时的常量池信息。 3、java堆:在虚拟机启动的时候建立,几乎所有的java对象实例存放在java堆中,堆空间是所有线程共享的。 4、直接内存:java的nio库允许使用直接内存,直接内存是在java堆外的、直接向系统申请的内存空间。通常访问直击内存的速度会优于 java堆,因此出于性能的考虑,读写频繁的场合可能会使用直接内存。由于直接内存存在java堆外,因此他的大小不会直接受限于Xmx指定 大小,但是系统内存是有限的,java堆和直接内存的综合依然受限于操作系统给出的最大内存。 5、Java栈:每一个java虚拟机线程都有一个私有的java栈,一个线程的java栈在线程创建的时候被创建,java栈中保存着祯信息,java 栈中保存着局部变量、方法参数,同时和java方法的调用、返回密切相关。 6、本地方法栈:和java栈类似,最大的不同在于Java栈用于java方法的调用,而本地方法栈用于本地方法的调用。 7、PC寄存器:它也是每个线程的私有空间,java虚拟机会为每一个线程创建PC寄存器。 8、垃圾回收系统:java虚拟机的重要组成部分,垃圾回收器可以对方法区、java堆和直接内存进行回收,Java堆是垃圾回收器的工作重点。 9、执行引擎:java虚拟机最核心组件之一,负责执行虚拟机的字节码。
三、Jvm参数配置
当使用GC打印日志的时候,以下信息的定义,新生代(new generation),老年代(tenured generation), 永久区 (compacting perm gen)。
jvm参数设置
序号 | 分类 | 命令行 | 解释 | jdk版本 |
1 | java堆配置 | -XX:+PrintGC | 打印GC日志,简略版 | 任意版本 |
2 | java堆配置 | -XX:+PrintGCDetails | 打印GC日志,详细版 | 任意版本 |
3 | java堆配置 | -XX:+PrintVMOptions | 查询项目的jvm设置了哪些参数配置 | 任意版本 |
4 | java堆配置 | -XX:PrintCommandLineFlags |
查询项目jvm配置了哪些参数,包括一些虚拟机启动自己配置的参数 | 任意版本 |
5 | java堆配置 | -Xms | 初始堆空间大小 | 任意版本 |
6 | java堆配置 | -Xmx | 最大堆空间大小 | 任意版本 |
7 | java堆配置 | -Xmn | 新生代大小,他一般为整个堆空间的1/3到1/4左右 | 任意版本 |
8 | java堆配置 | -XX:SurvivorRatio | 设置eden区和from/to空间比例 | 任意版本 |
9 | java堆配置 | -XX:NewRatio | 老年代/新生代空间比例 | 任意版本 |
10 | java堆配置 | -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath |
一起使用,可以找到堆空间不足导致溢出的java类信息 |
任意版本 |
11 | 方法区配置 | -XX:PermSIze | 永久区空间 | jdk6,7 |
12 | 方法区配置 | -XX:MaxPermSize | 永久区的最大大小 | jdk6,7 |
13 | 方法区配置 | -XX:MetaspaceSize | 元空间大小,默认128M | jdk8 |
14 | 方法区配置 | -XX:MaxMetaspaceSize | 元最大空间大小 | jdk8 |
15 | 栈配置 | -Xss | 指定线程的栈大小 | 任意版本 |
16 | 直接内存设置 | -XX:MaxDirectMemorySize | 最大内存设置,如不设置,默认值为最大堆空间,即Xmx,当直接内存达到最大值时,就会触发垃圾回收,如果垃圾回收不能有效释放足够空间,直接内存溢出引起系统OOM | 任意版本 |
配置方式一:
本地测试在idea上,如图:
配置方式二:
线上可使用:
java -jar -XX:MetaspaceSize=128m -XX:MaxMetaspaceSize=128m -Xms1024m -Xmx1024m -Xmn256m -Xss256k -XX:SurvivorRatio=8 -XX:+UseConcMarkSweepGC mjt-1.0.0.jar
四、垃圾回收算法
1、引用计数法 2、标记清除算法 3、复制算法 好处:建立在存活对象少,垃圾对象多的前提下,复制算法比较适用于新生代,因为在新生代,垃圾对象要多余存活对象,效果比较好。 4、标记压缩算法 标记清除算法的优化版,不只是清理未被标记的对象,而是将所有存活的对象压缩到内存的一端,之后清理边界外所有的空间,避免了碎片 的产生,又不需要两块相同的内存空间。(效果是标记清除算法之后,在进行一次内存碎片的整理)。 5、分代算法 新生代用复制算法,老年代用标记清除或标记压缩算法。 6、分区算法 将内存空间分成若干个区间,并不是一次性将所有空间回收,而是部分回收,减少停顿时间。
五、垃圾回收器
根据上面的算法思想创建垃圾回收器。
序号 | 种类 | 名称 | 使用的算法 | 定义 | jdk版本默认回收器 |
1 | 串行回收器 | 新生代串行回收器 | 复制算法 | 单线程垃圾回收,独占式,停止其他线程工作 | |
2 | 串行回收器 | 老年代回收器 | 标记清除算法 | 和新生代串行回收器一样,单线程,停顿时间更长 | |
3 | 并行回收器 | 新生代ParNew回收器 | 复制算法 | 多线程化,减少回收时间 | jdk1.6新生代 |
4 | 并行回收器 | 新生代ParallelGC回收器 | 复制算法 | 和新生代ParNew类似,不过的是更关注于系统吞吐量 | jdk1.7新生代和jdk1.8新生代 |
5 | 并行回收器 | 老年代ParalleOldGC回收器 | 标记压缩算法 | 多线程并发,同样是关注系统的吞吐量,jdk6才开始使用 | jdk1.7老年代和jdk1.8老年代 |
7 | 并行回收器 | CMS回收器 | 标记清除 | CMS不是独占式,它可以在程序运行过程中就可以垃圾回收 | jdk1.6老年代 |
8 | 分代垃圾回收器 | G1回收器 | 分区算法 | 它会区分老年代和新生代,选取部分区域垃圾回收,缩小垃圾回收范围 | jdk9 |
9 | 并发、基于区域、增量式压缩回收器 | ZGC回收器 | jdk11的linux支持,其他系统jdk11默认是G1 |
来源:oschina
链接:https://my.oschina.net/u/3209213/blog/3113699