1.JDK(支持java程序开发的最小环境):java程序设计语言,java虚拟机,java API类库
JRE(支持java程序运行的标准环境):java SE API子集,java虚拟机
2.java平台:Java Card支持java小程序(Applet);Java ME支持java程序在移动端;Java SE面向桌面;Java EE企业级应用
3.JDK1.5:自动装箱、泛型、动态注解、枚举、可变长参数、遍历循环(foreach)
JDK1.6:动态语言支持、编译API、微型HTTP服务器API、锁与同步、垃圾收集、类加载
JDK1.7:新的G1收集器、加强对非java语言的调用支持、升级类加载架构
JDK1.8:Lambda表达式
4.64位比32位额外增加10%~30%的内存消耗,1.6提供了普通对象指针压缩功能,但需要更多代码
1.运行时数据区
1.1程序计数器:当前线程执行的字节码的行号指示器,线程私有,没有OutOfMemeryError(OOME)异常
*如果执行的是java方法,计数器记录的是正在执行的虚拟机字节码指令的地址;如果执行的是Native方法,计数器为空
1.2虚拟机栈:用于存储局部变量表、操作数栈、动态链接、方法出口,线程私有,StackOverFlowError(SOFE)、OOME
1.3本地方法栈:执行Native方法,OOME、SOFE
1.4堆:存放对象实例,线程共享,可连续、可不连续,GC的主要区域,-Xmx堆的最大大小 -Xms堆的初始大小,OOME
1.5方法区:存储类信息、常量、静态变量,即使编译器编译的代码,线程共享,永久代,可不连续,OOME
1.6运行时常量池:存编译期生成的字面量和各种引用,运行期间也可能存常量,如String的intern(),OOME
1.7直接内存:1.4中加入了NIO类,引入了一种基于通道和缓冲区的IO方式,他可以使用Native函数库直接分配堆外内存,然后通过java堆里的DirectoryByteBuffer对象最为这块内存的引用,避免在java堆和Native堆之间来回复制
2.对象的创建(new 反射 克隆 反序列化)
虚拟机接到new-->检查是否被加载过-->没有就加载-->分配内存
如果内存规整,即占用的内存在一边,空闲的在另一边,指针在分界点,分配内存就是移动指针,分配内存称为“指针碰撞”
如果不规整,维护一个列表,分配空间给对象实例,然后更新列表,称为“空闲列表”
java堆是否规整由GC器是否带有压缩整理功能
分配完之后初始化为0值
3.对象的内存布局:对象头(Header)、实例数据(Instance Data)、对齐填充(Padding)
3.1对象头:第一部分用于存储对象自身的运行时数据,另一部分是类型指针确定对象是哪个类的实例
3.2实例数据:对象存储的有效信息
3.3对齐填充没意义,起占位符的作用
4.对象的访问定位:句柄、直接指针
句柄:在堆里划出一部分内存作为句柄池,对象名指向句柄,句柄包含对象实例数据和类型数据的地址信息
*优点:GC时对象位置移动时,不用改引用
直接指针:对象名指向new
*优点:速度快
5.线程请求的栈深度大于虚拟机允许的最大深度,抛StackOverFlowError
虚拟机栈在扩展栈时无法申请到足够的内存空间,抛OutOfMemeryError
*单线程下,无论栈太小还是内存不足,都抛StackOverFlowError
1.判断对象存亡方法
1.1.引用计数法
给对象添加一个引用计数器,每当有一个地方引用它,就加1,引用失效,就减1,为0时,对象不能再使用很难解决互相引用的问题
1.2.可达性分析算法
通过一系列被称为“GC Roots”的对象作为起点,当一个对象到GC Roots没有任何引用链时,该对象不可用
*GC Roots包括:虚拟机栈中引用的对象;方法区中类静态属性引用的对象;方法区中常量引用的对象;本地方法栈中JNI引用的对象
2.引用
强引用(GC不会回收)、软引用(有用但非必须)、弱引用(只能活到下次GC前)、虚引用
3.GC过程
可达性分析后没有引用链-->标记并筛选-->筛选条件是该对象是否有必要执行finalize()方法-->对象没有覆盖finalize()方法或已经被虚拟机调用过,则没必要执行finalize()-->有必要执行,把对象放入F-Queue队列,稍后执行一个虚拟机自动建立的,低优先级的Finalizer线程,去触发finalize()方法-->GC对对象第二次标记-->如果二次标记前被引用过,就死不了,否则被回收
4.GC算法
4.1.标记-清除算法:*缺点:效率低;产生不连续的内存碎片
4.2.复制算法:分代算法
4.3.标记-整理算法:标记后,让存活的向一段移动,其他的清掉,保证内存连续
5.何时何地GC
5.1.安全点:程序执行到安全点时才能执行GC
*选择标准:可以让程序长时间执行的地方
主动式中断:GC需要中断线程的时候,不去直接对线程操作,而是设置一个标志,线程轮询这个标志,标志为真时自己中断
5.2.安全区域:一段代码片段中,引用关系不会发生改变,在这里GC是安全的
6.分配策略
优先进入Eden;
大对象直接进入老年代;
年龄到一定程度(默认15岁)进入老年代;
survivor中相同年龄所有对象大小的和大于等于survivor的一半,这些对象以及比它们年龄大的对象进入老年代