jvm

讲的好的链接(https://www.zhihu.com/question/20097631)

 

jvm三个主要的子系统:

(1)类加载子系统                             

 (2)运行时数据区(内存结构)

(3)执行引擎

 

 

 

运行时数据区(内存结构)

java native关键字

 简单地讲,一个Native Method就是一个java调用非java代码的接口。一个Native Method是这样一个java的方法:该方法的实现由非java语言实现,比如C。

 

 程序计数器

 

java栈(8种基本类型的变量+对象的引用变量+实例方法)

 

 把栈撑爆,出现错误

 

栈帧中存放(局部变量表,操作数栈,执行运行时常量池的引用,方法返回地址,动态链接)

 

 黄色部分是线程共享的,蓝色部分是线程私有的

堆中存放对象(1.7之前是永久代,1.7之后是元空间)

方法区中存放全局变量(静态变量),常量,类信息等(运行时常量池)【存储了每一个类的结构信息】

 

 

私有的:像局部变量等属于线程私有的

 

 https://www.cnblogs.com/alsf/p/9017447.html

堆中分为:新生儿(Eden),from(s0区域),to(s1区域),当Eden放满之后,会发生轻gc(没用的对象进行垃圾回收),没有回收的对象转移到from(s0)区域,from区域放满之后也会触发轻gc,存活下来的对象会转移到to区域,然后to区域变成from区域,from区域变成to区域,来回变换一定的次数后,最终存活下来的对象放入到老年代,老年代放满之后会发生中gc(fullgc).老年代中存放的是存活时间成或者比较大的对象。

 

 

 

 

jvm类加载机制

生命周期:加载-》连接(验证,准备,解析)-》初始化-》使用-》卸载

加载:将字节文件(.class文件)从磁盘读到内存

类加载器的种类:

(1)启动类加载器:负责加载JRE的核心类库,如JRE目标下的rt,jar,charsets.jar等

(2)扩展类加载器:加载JRE扩展目录ext中的jar包

(3)系统类加载器:加载classpath路径下的类包(如:加载用户写的类)

(4)用户自定义类加载器:加载用户自定义路径下的类包

 

类加载机制:

(1)全盘负责委托机制:是指当一个ClassLoader装载一个类时,除非显示地使用另一个ClassLoader,则该类所依赖及引用的类也由这个CladdLoader载入。

(2)双亲委派机制:指先委托父类加载器寻找目标,在找不到的情况下在自己的路径中查找并载入目标类(防止用户自定义类捣乱)

(上边是父类)

启动类加载器(boot classload)
扩展类加载器(ext cl)
系统类加载器(app cl)

 

双亲委派模式的优势

沙箱安全机制:比如自己写的String.class类不会被加载,这样防止核心库被随意篡改

避免类的重复加载:当父加载器已经加载了该类的时候,就不需要子加载器再加载一次。

 

GC算法和收集器

(1)如何判断对象可以被回收

java堆内存中存放着几乎所有的对象实例,垃圾收集器在对堆进行回收前,第一件事情就是要确定这些对象之中哪些还“存活”着,哪些已经“死去”。那么GC具体通过什么手段来判断一个对象已经”死去”的?

【1】引用计数法

给对象中添加一个引用计数器,每当有一个地方引用它时,计数器值就加1,当引用失效时,计数器减1,任何时刻计数器为0的对象就是不可能再被使用的。

缺点:目前主流的java虚拟机都摒弃掉了这种算法,最主要的原因是它很难解决对象之间相互循环引用的问题。尽管该算法执行效率很高。

 

【2】可达性分析算法

目前主流的编程语言(java,C#等)的主流实现中,都是称通过可达性分析(Reachability Analysis)来判定对象是否存活的。这个算法的基本思路就是通过一系列的称为“GC Roots”的对象作为起始点,从这些节点开始向下搜索,搜索所走过的路径称为引用链(Reference Chain),当一个对象到GC Roots没有任何引用链相连(用图论的话来说,就是从GC Roots到这个对象不可达)时,则证明此对象是不可用的。如下图所示,对象object 5、object 6、object 7虽然互相有关联,但是它们到GC Roots是不可达的,所以它们将会被判定为是可回收的对象。

 

 在Java语言中,可作为GC Roots的对象包括下面几种:

  • 虚拟机栈(栈帧中的本地变量表)中引用的对象。
  • 方法区中类静态属性引用的对象。
  • 方法区中常量引用的对象。
  • 本地方法栈中JNI(即一般说的Native方法)引用的对象。

 (2)垃圾回收算法

https://blog.csdn.net/yrwan95/article/details/82829186

(1)标记-清除算法

(2)复制算法

(3)标记-整理算法

(4)分代回收

Eden(标记-清除算法)【标记-清除算法:节约空间,有内存碎片】,from to(复制算法)【复制算法:好处,没有内存碎片,坏处,费内存】,老年代(标记-整理算法),分代回收(jvm采用的就是这种算法)

(3)垃圾收集器

 

 Serial收集器(串行):单线程收集器,垃圾收集的时候必须暂停其他的工作线程,即STW(stop the world)(新生代采用复制算法,老年代采用标记-整理算法)

ParNew收集器:多线程收集器(多条垃圾收集线程),垃圾收集的时候必须暂停其他的工作线程,即STW(stop the world)(新生代采用复制算法,老年代采用标记-整理算法)

Parallel Scavenge收集器(jdk8默认的):吞吐量优先收集器

CMS收集器

优点:并发收集(垃圾收集与用户线程一起“并发”执行的。),低停顿

缺点:(1)对CPU资源敏感(2)无法处理浮动垃圾(垃圾收集过程中新产生的垃圾)(3)使用的是标记-清除算法,会导致收集结束时有大量的空间碎片。

G1收集器

调优

JVM调优主要是调整下面两个指标

(1)停顿时间:垃圾收集器做垃圾回收中断应用执行的时间。-XX:MaxGCPauseMillis

(2)吞吐量:垃圾收集的时间和总时间的占比:1/(1+n),吞吐量为1-1/(1+n)。-XX:GCTimeRatio=n

GC调优步骤:(https://www.cnblogs.com/baizhanshi/p/6140925.html?utm_source=itdadao&utm_medium=referral)

(1)打印GC日志

-信息:+PrintGCDetails -xx:+PrintGCTimeStamps -xx:+PrintGCDateStamps -xloggc:./gc.log

(2)分析日志得到关键性指标

(3)分析GC原因,调节JVM参数

 JMM(java内存模型)(线程安全性获得保证)

(1)可见性

(2)原子性

(3)有序性

 

加载顺序:静态代码块-》构造块-》构造方法

 

posted @ 2020-05-15 11:07  hulifang  阅读(136)  评论(0编辑  收藏  举报