• 架构图

  • 基本概念说明

    • 堆(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. jquery简易tab切换

    切换tab 使用eq()函数 eq() 方法将匹配元素集缩减值指定 index 上的一个. //为项目 3 设置红色背景 <ul> <li>list item 1</li ...

  2. CentOS 6.5优化开机启动服务

    使用chkconfig命令列举出所有服务,配合管道筛选出开机默认启动的服务,再去掉level0(关机).level4(无意义)和level6(重启)的显示,使结果更直观. chkconfig | gr ...

  3. Python爬虫——你们要的王者荣耀高清图

    曾经144区的王者 学了计算机后 头发逐渐从李白变成了达摩 秀发有何用,变秃亦变强 (emmm徒弟说李白比达摩强,变秃不一定变强) 前言 前几天开了农药的安装包,发现农药是.Net实现的游戏 虽然游戏 ...

  4. UI自动化(六)js

    HTML中的三把利器的JS 又称为JavaScript,看着好像和Java有点联系,实际上他和java半毛钱关系都没有,JavaScript和我们学习的Python.Go.Java.C++等,都是一种 ...

  5. Spring错误——Spring xml注释——org.xml.sax.SAXParseException; lineNumber: 24; columnNumber: 10; cvc-complex-type.2.3: 元素 'beans' 必须不含字符 [子级], 因为该类型的内容类型为“仅元素”。

    背景:配置spring xml,注释xml中文件元素 错误: Caused by: org.xml.sax.SAXParseException; lineNumber: 24; columnNumbe ...

  6. POJ 2774 Long Long Message (二分 + Hash 求最长公共子串)题解

    题意:求最长公共子串 思路:把两个串Hash,然后我们把短的作为LCS的最大可能值,然后二分长度,每次判断这样二分可不可以.判断时,先拿出第一个母串所有len长的子串,排序,然后枚举第二个母串len长 ...

  7. Pandas 基础(12) - Stack 和 Unstack

    这节的主题是 stack 和 unstack, 我目前还不知道专业领域是怎么翻译的, 我自己理解的意思就是"组成堆"和"解除堆". 其实, 也是对数据格式的一种 ...

  8. 3分钟快速presentation

    来自英语课的一个练习: https://www.youtube.com/watch?v=ePY3uY1L0X0 next up I'd like to welcome Joshua to ten he ...

  9. mac os使用迁移助手之后运行php报:dyld相关错误,错误排错流程分析

    在执行php相关命令的时候,报如下错误: dyld: Library not loaded:/usr/local/opt/openldap/lib/libldap-2.4.2.dylib Refere ...

  10. 『Argparse』命令行解析

    一.基本用法 Python标准库推荐使用的命令行解析模块argparse 还有其他两个模块实现这一功能,getopt(等同于C语言中的getopt())和弃用的optparse.因为argparse是 ...