• 架构图

  • 基本概念说明

    • 堆(heap):数据存储,对象实例;空间往上增长,线程共享区;大小可通过-Xmx和-Xms配置

      • 新生代(Young Generation):划分为Eden Space和两个Survivor(From Space 和To Space),new object首先存放在Eden区,Eden空间不足,进行GC,将存活的对象放到From Space;如果From Space已满,再进行GC,将存活的对象放到To Space;如果To Space已满,则再次GC,将存活的对象放入旧生代(Old Generation);可用-XX:survivorRatio控制Eden和Survivor的比例(默认值为8,即Eden占8/10, 另两个survivor各占1/10),或-Xmn配置新生代;-XX:NewSize和-XX:MaxNewSize分别代表新生代的初始值和最大值;
      • 旧生代(Old Generation):存放新生代经过三次垃圾会后仍存活的对象,如果旧生代已满,进行FullGCC,如果FullGCC后仍然无法存储对象,则报OutOfMemoryError(原因:要么heap设置大小不够;要么应用创建太多对象,且由于被引用而长时间不能被回收);
      • 持久代(Permanent Generation):存放类的元数据(方法、字段、类和包上描述数据,如注解Annotation,注释等,元数据可用于创建文档,跟踪代码中的依赖性如重构或重载,执行编译时检查,代码分析)、常量池、静态变量;如果出现OutOfMemoryError: PermGen space,原因有二:加载jar太多;或大量动态反射的类生成;可通过-XX:PermSize和-XX:MaxPermSize配置初始值和最大值;JDK1.8后将元数据移植到本地内存(好处:如多个项目的共享jar在本地内存只有一份),HotSopt VM为其分配或释放内存;可通过-XX:MetaspaceSize 和 -XX:MaxMetaspaceSize配置大小;
      • JDK1.8后将元数据存放在Metaspace区域(本地内存,取代method area区域),常量池和静态变量仍在Heap的持久代中;

    • 栈(stack):程序执行,处理数据;空间动态增长(对象可垃圾回收),一个线程对应一个栈,每个方法对应一个frame,其中存储局部变量(局部变量区),方法返回值和程序运行产生的中间值(操作数栈)。基本类型长度固定(不会动态增长),需要空间较小,存放栈中;也存放对象引用;Object ob = new Object()一个最基本的对象,占用空间:占的空间为:4byte(栈)+8byte(堆);如Class A{

          int i;
          boolean b;
          Object obj;
      },其大小为:A(8byte)+int(4byte)+boolean(1byte)+引用(4byte)=17byte,但分配时为8的倍数,所以空间为24byte。
    • PC Register:存储了下一条将要执行的指令;
    • class load 机制

      • Custom ClassLoader: 应用程序自定义的ClassLoader, 如Tomcat会根据J2EE规范自行实现ClassLoader加载过程中,会检查类是否已被加载(自下而上),只要某个ClassLoader已加载即可,否则会自上而下加载该类。
      • Link:二进制字节码格式校验;静态变量默认值赋值;检验类、接口中属性和方法的存在,否则抛出NoSuchMethodError、NoSuchFieldError。
      • Initialize: 静态初始化代码、构造器代码以及静态属性的初始化;new对象;反射调用类中的方法;子类调用了初始化;JVM启动过程中指定的初始化类。
    • JVM垃圾回收过程:垃圾回收的频率和时间是检验程序运行好坏的标准(因为回收时要停顿应用);

      • 清理Eden和Survior的GC叫Minor GC;清理old区域的叫Major GC;清理整个Heap的叫Full GC;
    • 哪些对象可被回收:
      • 引用计数算法:每创建一个对象,给其分配一个引用计数变量,并置值为1;当把该变量赋值给任何其它变量时,引用计数加1;当一个实例对象的引用生命周期结束或被修改时,该实例的引用计数减1;一个引用计数为零的对象将被垃圾回收,同时该对象引用其它对象的引用计数器减1。

        • 缺点:无法检测出循环引用,如父对象有对子对象的引用,子对象也有对父对象的引用;
        • 优点:执行效率高(可程序执行中交织进行)
      • 可达分析算法:通过从对象GC ROOT的引用关系开始分析,逐层画出一个引用关系图节点图,最后剩余节点被认为没有引用到,可垃圾回收(还会进行两次标记,最后确定是否回收);GC ROOT对象包括:栈中引用对象;方法区中静态属性引用的对象;方法区中常量引用的对象;本地方法栈中JNI引用的对象;
      • 引用分类:强引用(如Object obj = new object()),软引用,弱引用,虚引用,引用计数和可达分析算法都是基于强引用。
      • 方法区中常量和类的回收:前者可通过可达性分析进行回收;后者需同时满足:该类所有实例是否都已回收?加载该类的ClassLoader是否已经回收?该类对应的java.lang.Class对象是否在别的地方有被引用(确定无反射访问)?
    • 垃圾回收算法
      • 标记-清除算法:使用从根集合(GC Roots)进行扫描,对存活的对象进行标记,完成标记后,再扫描整个空间,对没有标记的对象进行垃圾回收;该算法不需要移动对象,当存活对象较多时,该算法较为高效,但会产生内存碎片;
      • 复制算法:为克服句柄开销和解决内存开销,将堆分为对象区和空闲区,当对象区已满,将对象区的存活对象复制到空闲区,这样将原来的对象区转变为空闲区,又可存放新的对象;
      • 标记-整理算法:与标记-清除算法不同的是,在回收没有引用的对象后,将存活对象往左端空闲空间移动,同时更新对应指针;该算法成本较高,但解决了碎片问题;
      • 分代收集算法(目前JVM常用算法):根据对象存活的生命周期,将对象划分为新生代(有大量对象回收)、老生代(较少对象回收)和永久代(不回收),不同代采用不同回收算法;
        • 新生代分为eden+survior0+survior1(比例8:1:1),新生对象放在eden中,垃圾回收时(不一定eden满),将eden中存活的对象复制到survior0,然后清空eden,如果survior0满,则将eden和survior0中存活对象复制到survior1,然后清空eden和survior0,再交换survior1和survior0(此时survior0为空),保持survior1为空,再循环以上过程;如果survior1不能存放eden和survior0中存活对象时,将存活对象复制到老年代;如果老年代也满,即触发Major GC(Full GC),新生代和老年代都进行垃圾回收(新生代叫Minor GC,频率较高)。
        • 老年代存放生命周期较长的对象(在新生代经过多次垃圾回收仍然存活的对象),内存空间大概是新生代2倍或以上。
        • 持久代存放静态文件,如java类,垃圾回收对该区没有多大影响;如果应用动态生成有大量类或调用累,需要将该区设置一个较大空间。
    • 垃圾收集器
      • 串行收集器(Serial Collector,复制算法):新生代单线程收集器(标记和清除都是单线程),是client模式默认的GC,简单高效,也可通过-XX:+UseSerialGC强制指定别的GC方式;
      • 串行老年代收集器(Serial Old Collector,清除-标记算法):老年代单线程收集器;
      • 并行新生代收集器(ParNew Collector,停止-复制算法):新生代并行收集器,在多核CPU环境下,比串行收集器效率更高;
      • Parallel Scavenge收集器(停止-复制算法):并行收集器,高效利用CPU以获得高吞吐量(用户线程时间/(用户线程时间+GC线程时间)),server模式默认采用的GC方式;可用-XX:+UseParallelGC和-XX:ParallelGCThreads指定GC方式和GC线程数;
      • Parallel Old Scavenge收集器(停止-复制算法):老年代并行收集器(吞吐量优先);
      • CMS收集器(Concurrent Mark Sweep,标记清理算法):高并发,低停顿(GC回收时暂停应用),响应快,尤适合多CPU。
    • Scanvenge GC和Full GC
      • 当Eden申请新生成对象空间失败时会出发Scanvenge GC;
      • 4种情况触发Full GC:年老带已满(Tenured);持久代已写满(Perm);System.gc()被显示调用;上一次GC后Heap各域分配策略动态变化;
    • 执行引擎(Execution Engine):字节码由一个个指令单元组成,每个指令有一个字节的操作码和操作数组成,执行引擎逐一读取这些指令;但字节码语言是人类可以理解的语言,需要再将bytecode转化成JVM machine能执行的语言;
      • 解释器(Interpreter):逐一读取、解释、执行字节码指令;可迅速解释一条指令,但执行指令较慢;
      • JIT (Just-In-Time) compiler:作为补偿Interpreter的一种手段,首先运行Interpreter, 然后在合适的时机,将所有的bytecode转化为native code直接执行,而且native code保存在缓存中,所以执行效率很高。
      • HotSpot采用编译器和解释器混合使用,HotSpot会将一些频繁调用的方法和代码(也叫热点代码Hot Spot Code)在运行时编译成native code;HotSpot内置两个编译器:client compiler(C1)和server compiler(C2), 程序采用哪个取决于JVM的运行模式设置;
      • 为了平衡启动响应速度和运行效率,HotSpot会采取逐层编译机制(Tiered compilation),JDK1.7的server complier默认开启该机制:

第0层:程序解释执行,解释器不开启性能监控,可触发第一层编译。 
第1层:也称为C1编译(更好的编译速度),将字节码编译为本地代码,进行简单、可靠的优化。 
第2层:也称为C2编译(更好的编译质量),也是将字节码编译为本地代码,但会启用一些编译耗时较长的优化,甚至会根据性能监控信息进行一些不可靠的激进优化。

    • 补充说明1:基本类型byte,boolean(1 byte),short,char(2 bytes),int,float(4 bytes),long,double(8 bytes);

JVM Optimization的更多相关文章

  1. Q&A to prepare interview of HSBC

    1.How do you keep updating lastest IT knowledge? 1).keep an eye on current project technology evetho ...

  2. Tomcat APR & Linux Optimization

    一.简介 APR(Apache portable Run-time libraries)模式:简单理解,就是从操作系统级别解决异步IO问题,大幅度的提高服务器的处理和响应性能, 也是Tomcat运行高 ...

  3. 关于JVM的类型和模式

    原文出处: 摆渡者 引言 曾几何时,我也敲打过无数次这样的命令: 然而之前的我都只关心过版本号,也就是第一行的内容.今天,我们就来看看第3行输出的内容:JVM的类型和工作模式. 其实说Server和C ...

  4. Java Performance Optimization Tools and Techniques for Turbocharged Apps--reference

    Java Performance Optimization by: Pierre-Hugues Charbonneau reference:http://refcardz.dzone.com/refc ...

  5. java源码剖析: 对象内存布局、JVM锁以及优化

    一.目录 1.启蒙知识预热:CAS原理+JVM对象头内存存储结构 2.JVM中锁优化:锁粗化.锁消除.偏向锁.轻量级锁.自旋锁. 3.总结:偏向锁.轻量级锁,重量级锁的优缺点. 二.启蒙知识预热 开启 ...

  6. java jvm和android DVM区别

      本文转自:http://blog.csdn.net/yujun411522/article/details/45932247   1.Android dvm的进程和Linux的进程, 应用程序的进 ...

  7. jvm.option是什么,它是如何加载的

    jvm.option是一些程序里边的java的配置参数的一个集合,不同的应用都会定义自己的jvm.options用来控制一些jvm的参数 以下,以elasticsearch为例,来说明它是如何加载的 ...

  8. JVM致命错误日志(hs_err_pid.log)分析

    当jvm出现致命错误时,会生成一个错误文件 hs_err_pid<pid>.log,其中包括了导致jvm crash的重要信息,可以通过分析该文件定位到导致crash的根源,从而改善以保证 ...

  9. New JVM Option Enables Generation of Mixed-Mode Flame Graphs

    转自 https://www.infoq.com/news/2015/08/JVM-Option-mixed-mode-profiles Java has added a new launch opt ...

随机推荐

  1. Python 语言来编码和解码 JSON 对象

    Json函数: json.dumps: Python标准库中的json模块,集成了将数据序列化处理的功能. 将 Python 对象编码成 JSON 字符串 语法: json.dumps(obj, sk ...

  2. 我设计的电脑usb红外遥控键盘原理图

    我设计的电脑usb红外遥控键盘,orcad原理图备份如下:

  3. 20190402Linux常用命令week1.1

    Linux常用命令详解week1.1 基础命令:lsmanpwdcdmkdirechotouchcpmvrmrmdircatmorelessheadtailclearpoweroffreboot 命令 ...

  4. C#使用NPOI导出Excel

    当记录数超出65536时,有两种方式处理: 一是调用WriteToDownLoad65536方法建立多个Excel. 二是调用WriteToDownLoad方法在同一个Excel中建多个Sheet. ...

  5. Ubuntu 16.04下vsftpd 安装配置实例

    从https://www.linuxidc.com/Linux/2017-06/144807.htm转载 第一步:安装VSFTPD sudo apt-get install vsftpd 安装完成后启 ...

  6. python之路——模块和包

    阅读目录 一 模块 3.1 import 3.2 from ... import... 3.3 把模块当做脚本执行 3.4 模块搜索路径 3.5 编译python文件 二 包 2.2 import 2 ...

  7. linux基础之awk

    gawk - pattern scanning and processing language 基本用法: gawk [options] 'program' FILE... program: PATT ...

  8. IdentityServer4支持的授权类型以及组合

    支持的授权类型: implicit hybrid authorization_code client_credentials password 支持的组合: implicit implicit,cli ...

  9. 解决Intellij IDEA中console窗口中文乱码的问题

    配置完tomcat之后,测试运行时,中文是乱码,如下图(自己忘截图了,图源网络,看水印) 网上其他的修改方法我就不说了,至少我试了一个都没用. 下面两个方法也是网上的,在此总结一下: 1.在idea. ...

  10. C#设置IE代理

    public class IEProxySetting { public static bool UnsetProxy() { return SetProxy(null, null); } publi ...