简述
Java的诞生,从还叫Oak语言的时间算起来,已有近三十年。这三十年间,Java不断进化的不只是使用、语法、高层框架,更加核心的是JVM虚拟机及其组成部分的升级,不断的适应着时代的需求。
发展历程
时间 | 事件 | JVM相关 |
---|---|---|
1991 年 | Oak语言诞生,目标(机顶盒、收音机等)的消费性电子产品 | |
1995年 | Oak改名Java | |
1996年 | JDK1.0发布,技术包括虚拟机、Applet、AWT等 | Sum Classic VM(一款纯解释型虚拟机) |
1997年 | JDK1.1,技术包括 JAR、JDBC、JavaBeans、RMI | |
1998年 | JDK1.2,Java拆分J2EE、J2SE、J2ME | 99年HotSpot诞生,附加在Java(王者之路的开始),内置JIT编译期 |
2000年 | JDK1.3,类库改进、JNDI | |
2002年 | JDK1.4,正则、异常链、NIO等 | |
2004年 | JDK5(开始改用JDK X),语法易用性改进:自动装箱等。 | 改进Java内存模型JMM |
2006年 | JDK6 编译期注解处理器、微型HTTP服务器API。 | 改进锁与同步、垃圾收集、类加载等。 |
2009年 | JDK7, Sun Java成为Oracle公司下的Oracle Java | 提供G1收集器 |
2014年 | JDK8,Lambda、时间API | 移除HotSpot永久代,方法区移动到直接内存,重名为 元空间(MetaSpace) |
2017年 | JDK9,模块化Jigsaw,从此三个大版本才会长期维护,上一个是JDK8,下一个是JDK11 | G1成为默认垃圾收集器 |
2018年3月 | JDK10,内部重构 | 统一垃圾收集器接口/即时编译器接口 |
2018年9月 | JDK11,ZGC | ZGC垃圾收集器 |
2019年 | JDK12,Switch表达式 | OpenJDK加入Shenandoah垃圾收集器 |
内存布局
我们都常说堆栈,那么实际在Jvm、或者说实际最多使用的HotSpot虚拟机中,整体的内存是如何布局的呢?
- 栈
方法栈,一个存在于计算机中的栈结构,用于存储运行时方法。方法栈的每一个元素称为栈帧,代表一个方法。栈的顶端是当前在执行的方法,执行完毕之后会出方法栈,新的方法被调用也会首先入方法栈。
栈帧:一个栈帧内部包含局部变量表、动态链接(持有指向常量池的引用)、方法出口等信息。 - 堆
内存堆,Java虚拟机规范中,堆是一切实例对象存在的地方,实际上有例外。是垃圾回收算法应用的地方,也是最容易发生OOM的地方。
堆在JDK1.8之前都是分代论(即新生代、Survivor区、老年代、永久代),JDK1.8移除了永久代,而JDK1.9则直接摒弃了传统分代论,采用G1收集器的Region分区实现新生区、老年区和大对象区。 - 方法区
方法区(JDK1.8之后称为元空间)用于存储类的基本信息、运行时常量池(基本上就是class文件记录的这些东西)。
JDK1.8之前,方法区一直作为永久代,实现在堆内存。在JDk1.8之前,改名元空间,并放到了直接内存(也叫对外内存) - 本地方法栈
类似虚拟机栈,只不过存储的都是对接其他语言的本地方法。 - 程序计数器
程序计数器记录正在执行的虚拟机字节码指令的地址。