JVM知识整理

byzhj 639 0
温馨提示

此为后端学习第一篇,后续会将之前整理的学习笔记上传。

一.历史

  • 技术和时间点
    • 1996,JDK1.0:虚拟机和AWT、Applet
    • 1997,JDK1.1:内部类、反射、jdbc、jar
    • 1998,JDK1.2:swing、三大分类(SE、EE、ME)、collection
    • 2000年,JDK1.3,hotspot成为御用商用虚拟机。
    • 2002,JDK1.4:正则、异常链、nio,.net框架的竞争加入
    • 2004,JDK5:泛型、枚举、自动装箱等语法,还有juc
    • 2006,JDK6:开源、http的api、注解处理器,2009被收购。
    • 2011,JDK7:sun被收购后的商业化探索
    • 2015,JDK8:日期API、Lambda、永久代移除
    • 2018,JDK11:Android遭大重,因为API有版权;放弃javaEE(含有servlet、JDbc等组件);出现OracleJDK商用模式。
    • 2019,JDK12:RedHat接手历史版本维护,OracleJDK首次出现和openJDK不一样。

 

  • 几个重要概念
    • JCP(Java Community Process):主要由Java开发者以及被授权者组成,职能是发展和更新
    • JEP(JDK Enhancement Proposals):由Oracle成立来管理新版本JDK的发布功能。

 

  • 虚拟机
    • JavaME的CLDC—如今只能在老人机里有市场
    • JavaSE的HotSpot—如今已经融合了jrockit的监控,一家独大。
    • apache和Dalvik:apache退出jcp组织;谷歌的Dalvik基于寄存器架构,所用的类库也不一样。

 


 

 

二.内存

  • 1.程序计数器

    • 概念:线程私有,唯一一个没有过oom的区域。
    • 作用:记录程序运行指令下一跳内存地址——解决多线程恢复问题和顺序执行

 

  • 2.栈

    • 概念:方法栈帧,线程私有
    • 栈帧组成:局部变量表、操作数栈、动态链接、方法出口。
      • 局部变量表:进入方法时的大小即变量槽数量是确认的。
    • 异常:栈溢出是StackOverflow,申请失败则是oom,hotspot不允许动态扩展。

 

  • 3.本地方法栈

    • 概念: hotspot实际上是本地和虚拟机栈合二为一实现的。
    • 作用:是调用别的c语言的库函数,native方法存放在此区

 

  • 4.方法区

    • 落地实现:7是永久代8是元空间,线程共享的。
    • 作用:存放类信息(类模板)、常量、静态常量、字符串常量。
    • 永久代:8之后被取消,存放的是jar包class等元数据方便加载、以前跟老年代抢空间、静态类信息也存这。
    • 元空间:存放类信息(类模板)

 

  • 5.常量池

    • 编译时规定常量池数据,也可以动态加入。8之后存在堆中
    • 内容:字面量和符号引用和直接引用。

 

  • 6.直接内存

    • nio :操作java堆上的DirectByteBuffer对象作为这块内存的引用
    • 0拷贝:绕过虚拟机堆空间,从直接内存复制到用户空间进行操作。

 

  • 7.堆

    • 理解:栈管运行引用,堆管空间——存的就是实例对象
    • 并发方面:线程共享,但可以有线程私有的分配缓冲区
    • 存有到方法区类模板的指针

 

8.对象的创建流程

  • 分配空间:
    • 指针碰撞法:适合内存规整,所以需要配合复制、标记清除压缩算法
    • 空闲列表:适合零散,比如标记清除
  • 本地线程缓冲区TLAB:解决多线程下的内存分配指针冲突,需要一段线程私有缓冲区。
  • 设置对象头:确定属于哪个类的类指针、gc的年龄
    • 锁状态、偏向id
    • 句柄

 


 

 

三.垃圾收集

垃圾收集

  • from(幸存者一区)和to区能交换——gc扫描eden和from存活去to
  • gc回收15次不到的去老年代
  • fullgc回收不行时报oom

 

垃圾标记算法

  • 引用计数器:计算机维护引用(已经弃用),因为无法解决循环引用。只有flashplayer、com等地方使用。
  • 可达性分析算法:gcroots跟对象,垃圾回收检查它拥有的引用链进行回收。
  • finalize():只会在对象第一次被回收时被执行一次。
    • 作用:对c++析构函数的一种妥协,开销极大,已经弃用。

 

垃圾收集算法

  • 复制:年轻代复制的from到to,优点是不会产生内存碎片,缺点是耗空间(预留两份空间),to满去old。
  • 标记清除:在survive区标记存活的清除可回收的,缺点是速度要扫描2次先标记再回收,会严重耗时,而且会产生碎片。
  • 标记压缩:标记清楚后再压缩一样腾出空间——缺点是压缩一样要时间

 

 

 


 

 

四.调优和工具

调优

  • 针对heap调优runtime对象表示运行时内存
  • 调jvm大小:xms64/1,xmx4/1,生产环境配一样防止争抢出现
  • 永久代:可调permmaxsize
  • eden和old:默认比例8:1:1可调比例
  • gc日志:记录回收多少内存

 

工具

  • jps
  • 可视化:
    • Jconsole:

 


 

 

五.类加载

Class文件结构

  • 概述:基于《虚拟机规范》级别的代码,可以由多种语言实现。

 

  • 文件格式:类似于c语言结构体,类型只有无符号和表。

 

类加载时机

  • 6种情况下:new、reflect包下的类方法、静态变量、静态方法、父类初始化、主类初始化

 

 

类加载过程

  • 加载
    • 通过全限定名读取二进制流文件

 

 

 

  • 连接

 

  • 初始化

 

类加载器

  • 三大加载器:层层调用的先调用底层的(沙箱安全)
    • bootstrap(c++):加载底层的类——rt.jar包启动类加载的包
    • extclassloader:javax包——java写的
    • appclassloader:自己编写的类的加载器
  • 双亲委派:委派给父类加载器去加载类

 


 

 

六.java内存模型(jmm)

 

  • 为了实现多线程——将物理上的内存分为工作内存(也是在堆里)和主内存。

发表评论 取消回复
表情 图片 链接 代码

分享