前言前端
做为Java程序员,你有没有被JVM伤害过?面试的时候是否碰到过对JVM的灵魂拷问?程序员
1、JVM 内存区域划分web
1.程序计数器(线程私有)面试
程序计数器(Program Counter Register),也有称做为 PC 寄存器。保存的是程序当前执行的指令的地址(也能够说保存下一条指令的所在存储单元的地址),当 CPU 须要执行指令时,须要从程序计数器中获得当前须要执行的指令所在存储单元的地址,而后根据获得的地址获取到指令,在获得指令以后,程序计数器便自动加 1 或者根据转移指针获得下一条指令的地址,如此循环,直至执行完全部的指令。也就是说是用来指示执行哪条指令的。算法
因为在 JVM 中,多线程是经过线程轮流切换来得到 CPU 执行时间的,所以,在任一具体时刻,一个 CPU 的内核只会执行一条线程中的指令,所以,为了可以使得每一个线程都在线程切换后可以恢复在切换以前的程序执行位置,每一个线程都须要有本身独立的程序计数器,而且不能互相被干扰,不然就会影响到程序的正常执行次序。所以,能够这么说,程序计数器是每一个线程所私有的。编程
在 JVM 规范中规定,若是线程执行的是非 native 方法,则程序计数器中保存的是当前须要执行的指令的地址;若是线程执行的是 native 方法,则程序计数器中的值是 undefined。数组
因为程序计数器中存储的数据所占空间的大小不会随程序的执行而发生改变,所以,对于程序计数器是不会发生内存溢出现象(OutOfMemory)的。缓存
异常状况:性能优化
不存在服务器
2.Java 栈(线程私有)
3.本地方法栈(线程私有)
4.堆(线程共享)
5.方法区(线程共享)
6.直接内存(线程共享)
2、JVM 执行子系统
1.Class 类文件结构
1.1 Java 跨平台的基础
各类不一样平台的虚拟机与全部平台都统一使用的程序存储格式——字节码(ByteCode)是构成平台无关性的基石,也是语言无关性的基础。Java 虚拟机不和包括 Java 在内的任何语言绑定,它只与“Class 文件”这种特定的二进制文件格式所关联,Class 文件中包含了 Java虚拟机指令集和符号表以及若干其余辅助信息。
1.2 Class 类的本质
任何一个 Class 文件都对应着惟一一个类或接口的定义信息,但反过来讲,Class 文件实际上它并不必定以磁盘文件的形式存在。Class 文件是一组以 8 位字节为基础单位的二进制流。
1.3 Class 文件格式
各个数据项目严格按照顺序紧凑地排列在 Class 文件之中,中间没有添加任何分隔符,这使得整个 Class 文件中存储的内容几乎所有是程序运行的必要数据,没有空隙存在。Class 文件格式采用一种相似于 C 语言结构体的伪结构来存储数据,这种伪结构中只有两种数据类型:无符号数和表。
无符号数属于基本的数据类型,以 u一、u二、u四、u8 来分别表明 1 个字节、2 个字节、4 个字节和 8 个字节的无符号数,无符号数能够用来描述数字、索引引用、数量值或者按照 UTF-8编码构成字符串值。
表是由多个无符号数或者其余表做为数据项构成的复合数据类型,全部表都习惯性地以“_info”结尾。表用于描述有层次关系的复合结构的数据,整个 Class 文件本质上就是一张表。
2.字节码指令
2.1 加载和存储指令
2.2 运算或算术指令
2.3 类型转换指令
2.4 建立类实例的指令
2.5 建立数组的指令
2.6 访问字段指令
2.7 数组存取相关指令
2.8 检查类实例类型的指令
2.9 操做数栈管理指令
2.10 控制转移指令
2.11 方法调用指令
2.12 方法返回指令
2.13 异常处理指令
2.14 同步指令
3.类加载机制
4.类加载器
4.1 系统的类加载器
4.2 双亲委派模型
5.Tomcat 类加载机制
6.方法调用详解
6.1 解析
6.2 静态分派
6.3 动态分派
6.4 基于栈的字节码解释执行引擎
三.垃圾回收器和内存分配策略
1.Java 中是值传递仍是引用传递?
2.引用类型
3.基本垃圾回收算法
3.1.1 引用计数(Reference Counting):
比较古老的回收算法。原理是此对象有一个引用,即增长一个计数,删除一个引用则减小一个计数。垃圾回收时,只用收集计数为 0 的对象。此算法最致命的是没法处理循环引用的问题。
3.1.2 可达性分析清理
标记-清除(Mark-Sweep):此算法执行分两阶段。第一阶段从引用根节点开始标记全部被引用的对象,第二阶段遍历整个堆,把未标记的对象清除。此算法须要暂停整个应用,同时,会产生内存碎片。
复制(Copying): 此算法把内存空间划为两个相等的区域,每次只使用其中一个区域。垃圾回收时,遍历当前使用区域,把正在使用中的对象复制到另一个区域中。次算法每次只处理正在使用中的对象,所以复制成本比较小,同时复制过去之后还能进行相应的内存整理,不会出现“碎片”问题。固然,此算法的缺点也是很明显的,就是须要两倍内存空间。
标记-整理(Mark-Compact):此算法结合了“标记-清除”和“复制”两个算法的优势。也是分两阶段,第一阶段从根节点开始标记全部被引用对象,第二阶段遍历整个堆,清除标记对象,并未标记对象而且把存活对象“压缩”到堆的其中一块,按顺序排放。此算法避免了“标记-清除”的碎片问题,同时也避免了“复制”算法的空间问题。
3.1 按照基本回收策略分
3.2 按分区对待的方式分
3.3 按系统线程分
4.分代处理垃圾
5.JAVA 中垃圾回收 GC 的类型
4、编写高效优雅 Java 程序
1.面向对象
1.1 构造器参数太多怎么办?
用 builder 模式,用在
(1)5 个或者 5 个以上的成员变量
(2)参数很少,可是在将来,参数会增长
Builder 模式:
属于对象的建立模式,通常有
(1)抽象建造者:通常来讲是个接口,包含
1)建造方法,建造部件的方法(不止一个)
2)返回产品的方法
(2) 具体建造者
(3) 导演者,调用具体的建造者,建立产品对象
(4)产品,须要建造的复杂对象
对于客户端,建立导演者和具体建造者,并把具体建造者交给导演者,而后由客户端通知导演者操纵建造者进行产品的建立。
在实际的应用过程当中,有时会省略抽象建造者和导演者。
1.2 不须要实例化的类应该构造器私有
1.3 不要建立没必要要的对象
1.4 避免使用终结方法
1.5 使类和成员的可访问性最小化
1.6 使可变性最小化
1.7 复合优先于继承
1.8 接口优于抽象类
2.方法
2.1 可变参数要谨慎使用
2.2 返回零长度的数组或集合,不要返回 null
2.3 优先使用标准的异常
3.通用程序设计
5、性能优化
一个 web 应用不是一个孤立的个体,它是一个系统的部分,系统中的每一部分都会影响整
个系统的性能
1.经常使用的性能评价/测试指标
1.1 响应时间
提交请求和返回该请求的响应之间使用的时间,通常比较关注平均响应时间。
经常使用操做的响应时间列表:
1.2 并发数
同一时刻,对服务器有实际交互的请求数。
和网站在线用户数的关联:1000 个同时在线用户数,能够估计并发数在 5%到 15%之间,也就是同时并发数在 50~150 之间。
1.3 吞吐量
对单位时间内完成的工做量(请求)的量度
1.4 关系
系统吞吐量和系统并发数以及响应时间的关系:
理解为高速公路的通行情况:
吞吐量是天天经过收费站的车辆数目(能够换算成收费站收取的高速费),并发数是高速公路上的正在行驶的车辆数目,响应时间是车速。车辆不多时,车速很快。可是收到的高速费也相应较少;
随着高速公路上车辆数目的增多,车速略受影响,可是收到的高速费增长很快;
随着车辆的继续增长,车速变得愈来愈慢,高速公路愈来愈堵,收费不增反降;
若是车流量继续增长,超过某个极限后,任务偶然因素都会致使高速所有瘫痪,车走不动,固然后也收不着,而高速公路成了停车场(资源耗尽)。
2.经常使用的性能优化手段
2.1 避免过早优化
2.2 进行系统性能测试
2.3 寻找系统瓶颈,分而治之,逐步优化
2.4 前端优化经常使用手段
3 应用服务性能优化
3.1 缓存
3.1.1 缓存的基本原理和本质
3.1.2 合理使用缓冲的准则
3.1.3 分布式缓存与一致性哈希
3.2 异步
3.2.1 同步和异步,阻塞和非阻塞
3.2.2 常见异步的手段
3.3 集群
3.4 应用相关
3.4.1 代码级别
3.4.2 并发编程
3.4.3 资源的复用
3.4.4 JVM
3.4.5 GC 调优
3.4.6 调优实战
3.4.7 存储性能优化
上面的这些问题只是给你们一个借鉴做用,最主要的是给本身增长知识的储备,有备无患。
关于JVM与性能调优总结了将近50页pdf文档,欢迎关注个人公种浩:程序员追风,获取这些整理的资料!
但愿能帮助到你面试前的复习且找到一个好的工做,也节省你们在网上搜索资料的时间来学习。
最后
欢迎你们一块儿交流,喜欢文章记得关注我点个赞哟,感谢支持!