jvm超简洁版提纲

jvm

位置

jre(java运行环境)位于操作系统之上,jre包含jvm

体系结构

类加载器(加载.class文件)与运行时数据区进行交互

运行时数据区

  • 不产生垃圾

    • 本地方法栈

    • 程序计数器

  • 产生垃圾

    • 方法区

类加载器

Class Loader加载.class文件

加载:.class文件->内存方法区->class对象

链接:静态变量分配内存

初始化:类构造器初始化

类加载器(三种)

启动类加载器:%JAVA_HOME%\bin jar包 rt.jar

拓展类加载器:%JAVA_HOME%\bin\ext jar包

系统类加载器:类路径指定类库

自定义类加载器

向上委托,到启动类加载器

父加载器失败由子加载器加载

避免重复加载,避免修改核心类

沙箱机制

限制运行环境,代码隔离,限制对本地资源访问

组件:

  • 字节码校验器:检验java语法规范,核心类不进行检验

  • 类装载器

    • 恶意代码

    • 类库边界

    • 保护域,以及代码权限

Native

示例:private native void start0();

native 超出java范围,调用c库

进入本地方法栈调用本地方法库

本地方法栈登记native方法,通过本地方法接口(JNI)加载

本地方法接口融合c,c++程序

pc程序计数器

线程私有,指针指向方法区中的指令字节码,存放指令地址

指令字节码:存储指向下一条指令的地址,即将执行指令地址

方法区

线程共享

字段、方法字节码、构造函数、接口

方法区:静态变量static,常量final、类信息:构造函数 接口定义、运行时的常量

示例变量堆内存

生命周期同线程、无垃圾回收问题

内存:8大基本类型,对象引用、实例方法(递归)

运行原理:栈帧

栈满:StackOverFlowError

栈帧组成:

  • 局部变量表

  • 操作数栈

  • 动态链接:符号引用转换成直接引用

  • 方法出口:栈中下一元素地址

反编译 javap -c xxx.class

一个类被加载到JVM中时,它的符号引用(比如方法、字段等)会被转化为直接引用(比如方法调用指令、字段访问指令等)

堆:一个,栈:一个线程一个线程栈

组成:

  • 新生区

    • 伊甸园区:new对象

    • 幸存0区:轻GC存活

    • 幸存1区:轻GC存活

  • 养老区:多次轻GC存活

  • 永久区(元空间):jdk自身class对象

GC回收:伊甸园区和养老区

99%对象是临时对象

永久区出现OOM:加载大量三方jar包,大量动态生成反射类,直至内存满

元空间:==逻辑存在,物理不存在==

存储本地磁盘,不在内存虚拟机中

jvm最大内存:电脑内存1/4

jvm初始内存:电脑内存1/64

总结

栈:基本数据类型,引用数据类型,实例对象的方法

堆:new出的对象和数组

方法区:Class对象,static变量,常量池

JPofiler分析OOM

idea安装插件

生成dump文件:-Xms1m -Xmx1m -XX:+HeapDumpONOutOfMemoryError

JVm调优常见参数

垃圾回收算法

引用计数算法

对象被引用计数加一,被释放减一

垃圾回收计数为0

致命缺点:无法处理循环引用

复制算法

划分内存相等两区域,每次使用一区域

机制:遍历当前使用区域,复制正使用对象到另一区域,清理当前区域

处理的是正使用的对象,复制成本小,复制后还可进行内存整理

优点:无碎片问题

缺点:两倍空间

标记-清除算法

两阶段:

  • 从引用根节点开始标记可回收对象

  • 遍历堆,清除未带标记的

优点:不浪费空间

缺点:暂停应用,内存碎片

标记-压缩算法

两阶段:

  • 从引用根节点开始标记可回收对象

  • 清除未标记节点,并且压缩存活对象,顺序排放

分代回收策略

  1. new对象放在伊甸园

  2. 伊甸园满,触发轻GC,回收伊甸园垃圾对象,存活对象放置幸存0区,1区为空

  3. 伊甸园再满,触发轻GC,回收伊甸园和0区垃圾对象,存活对象放置1区,0区为空

  4. 反复切换(默认15次),存活对象放置老年区

  5. 老年区满了触发全GC

轻GC:

  • 复制算法

  • 新生代满触发

  • 收集间隔短

重GC:

  • 标记压缩算法

  • 老年代满触发

  • 使用System.gc显示触发

  • 耗时,间隔长

垃圾收集器

串行收集器(Serial)

单线程收集,简单高效

新生代:复制算法

老年代:标记-整理

并行收集器(ParNew)

串行收集器多线程版

同上

Parallel Scavenge收集器

复制算法,并行多线程

优势:系统吞吐量

系统吞吐量=运行用户代码时间/(运行用户代码时间+垃圾收集时间)

Parallel Old收集器

单线程 标记整理算法 吞吐量优先

CMS收集器(Concurrent Mark Sweep)

多并发低暂停 标记-清除算法

获取最短回收停顿时间为目标

G1收集器

划分堆内存为大小相等独立区域

STW

问题:垃圾回收时,用户线程执行完了,堆中对象失去引用变成垃圾

解决:快速完成垃圾回收,再恢复用户线程运行

JMM

java内存模型

虚拟存在,规范,定义变量访问方式

线程与主内存:

  • 线程共享变量在主内存中

  • 每一线程有私有本地内存

  • 本地内存存储线程读写共享变量的副本

三大特性:

  1. 原子性:使用synchronized

  2. 可见性:使用volatile,synchoronized,final

  3. 有序性:指令重排

synchoronized:unlock前同步回主存

final:线程可见(注意this逃逸例外,线程通过this访问被final修饰的初始化一半的对象)

指令重排:源代码->编译器优化重排->指令并发重排->内存系统重排->最终执行的命令 不影响单线程执行,影响多线程并发执行的正确性

你可能感兴趣的:(java,1024程序员节,java,jvm)