1.jvm发展简要介绍
1996年,sun发公司发布了Sun Classic Vm(jdk1.2)。后来发展为Sun HotSpot vm(since jdk1.3)
2006宣布java开源,随后建立了Open jdk
2009年,oracle收购sun。
其他公司:JRockit VM,IBM J9 VM,Microsoft VM
2.java 内存区域与内存溢出异常
内存结构:程序计数器(线程私有) 、 虚拟机栈(线程私有) 、 本地方法栈(执行native方法)、 java堆、 方法区
java堆是虚拟机内存中最大的一块,被所有线程共享,主要用于存放对象实例,垃圾收集器的主要作用对象。现在通常采用分代收集算法,可以细分为新生代和老年代。java堆中又可能划分出多个线程私有的分配缓冲区。现在基本都是可以扩展的(-Xmx -Xms)
方法区:用于存储已经被虚拟机加载的类信息、常量、静态变量、即使编译后的代码等数据。-XX:PermSize=10M
运行时常量池:方法区的一部分。用于在类加载后进入方法区的运行时常量池存放。
对象的内存布局:分为3块区域:对象头、实例数据和对齐填充。对象头分为两个部分:一部分是存储对象自身的运行时数据,如hashcode、GC分代年龄、锁状态标志、线程持有的锁、偏向线程ID;另外一部分是类型指针,通过这个类确定这个对象是哪个类的实例。
如何访问对象:句柄和直接指针
3、垃圾收集器和内存分配策略
判断对象是否回收算法:
引用计数算法(不可用) 可达性分析算法
回收方法区:
新生代的回收率较高,一般为70%~95%,永久代回收率较低。
垃圾收集算法:1标记-清除 2复制算法 3.标记-整理算法 4.分代收集算法
HopSpot算法的实现:1.枚举根节点 2.安全点 3.安全区域
4.垃圾收集器
1.Serial收集器,新生代唯一的选择,单线程。
2.Paraller Scavage收集器,采用复制算法,使用新生代收集 --XX:MaxGcPauseMillis -XX:GCTimeRatio
3.Concurrent Mark Sweep(CMS)收集器,采用标记--清除算法,用作老年代收集,以获取最短回收停顿时间为目标,适合于互联网站或者BS系统的服务端上
4.Garbage First(G1)收集器
5.ParNew收集器,Serial多线程版本,唯一的可以和CMS一起运作的收集器 -XX:UseParNewGC
6.Serail Old收集器,Serail的老年代版本,使用标记--整理算法
7.Paraller Old收集器,Paraller scavenge的老年代版本,采用标记-整理算法
8.G1收集器,面向服务端应用的垃圾收集器。since jdk1.7 优点:并行与并发、分代收集、空间整合、可预测的停顿。新生代和老年代不再是隔离的,而是连续的。
4.虚拟机类加载
类的生命周期:加载--->验证(文件格式验证、元数据验证、字节码验证、符号引用验证)--->准备(准备变量的初始值)--->解析(类或接口的解析、字段解析、类方法解析、接口方法解析)--->初始化-->使用--->卸载
类加载器:
加载机制:BootStrap ClassLoader\Extention ClassLoader\Application ClassLoader\用户自定义加载器,采用的模式双亲委派模型
5.java多线程
怎么衡量一个服务性能的好坏?每秒事务处理数
java内存模型:主内存+工作内存+java线程,类似于处理器和二级缓存以及内存的关系
工作内存和主内存的交互操作:
lock unlock read load use assign store write
具有原子性:如read和load,store和write不允许单独出现
volitale关键字,开销小于锁,属于轻量级
线程的实现:1、使用内核线程实现(LWP) 2、使用用户线程实现 3.使用用户线程加轻量级进程混合实现 内核进程与线程是一对一的关系 进程与用户线程是1:N关系,且用户线程不需要内湖帮助,操作迅速且低消耗
线程调度:协同式线程调度和抢占式线程调度,协同方式线程执行时间由自己决定,抢占式由系统来分配时间
状态转换:是靠操作系统来支持的,比较消耗时间和资源。new -->runnable->terminated(blocked\wating\time-waiting)
6.多线程锁优化
线程安全的实现方法:1.互斥同步 (临界区、互斥量、信号量)状态转换需要耗费很多的处理器时间。所以synchronized是一个重量级封装。ReetranLock可以显示一些高级功能:公平锁、等待可中断、锁可以绑定多个条件。2.非阻塞同步 使用AtomicInteger,本质是靠java native方法实现 3.无同步方案 可冲入代码或者线程本地存储 ThreadLoacal
锁优化:
适应性自旋(原理,在线程阻塞时不会让线程放弃执行,而是执行一个忙循环) 锁消除(string 的contact方法) 锁粗化(当代码中的synchronized块太多的时候) 轻量级锁 偏向锁