【Diary】【2018-10-22】【JVM回顾】

昨天休息。。。真的懒得学习,今天继续,由于今天在公司所以只有jvm可看了。

先来复习一下,jvm的内存的结构和垃圾回收。

1、复习jvm内存模型

a.程序计数器

一块较小的内存空间,用来存储程序执行的字节码的行号指示器。这是唯一一个没有OutOfMemoryError的区域。(线程私有,生命周期和线程同生共死)

b、java虚拟机栈

描述java方法的执行模型,每个方法执行的时候都会创建一个栈帧用于存储局部变量表、操作数栈、动态链接、方法出口等信息。每一个方法从调用直至执行完成的过程,对应着一个栈帧的入栈和出栈的过程。通常意义上的栈内存指的就是虚拟机栈的局部变量表,存储了编译期间可知的各种数据类型、对象引用。其中64位的long和double会占用两个局部变量空间,其余的数据类型占1个,也就是一个局部变量空间为32位。(线程私有,生命周期和线程同生共死),拥有oom异常。

c、本地方法栈

本地方法栈和虚拟机栈的作用类似,他们的区别在于一个执行的是java方法,一个执行的是native方法。拥有oom异常和sof异常。

d、java堆(gc堆)

堆一般为jvm中占用内存最大的一块,java对是所有线程公用的内存区域,在jvm启动的时候被创建。主要用来存放java对象,线程共有的java堆会划分许多私有的分配缓冲区,TLAB。

c、方法区(永久代)

方法区和堆类似,都为线程共有区域,只不过它用来加载常量,静态变量,即时编译的代码等数据。存在oom异常

e、运行时常量池

它是方法区的一部分。用来存放class文件除了有类的版本,字段,方法,接口等描述信息外,还有一项是常量池(Constant Pool Table),用于存放编译期间生产的各种字面量和符号引用,这部分类容在类加载后存入方法区的运行时常量池中存放。

f、直接内存

Direct Memory is  not jvm’s data,同时也不是虚拟机规范中定义的内存区域。主要用于存储buffer对象的操作。

2、垃圾回收

  • 引用计数法

有引用+1无引用-1,无法解决对象之间的循环引用问题,即使对象已经不被使用,但是由于互相引用,无法清除该对象。

  • 可达性分析算法

通过GC Roots寻找存货对象,在java中可作为GC Roots的对象包括以下几种:

虚拟机栈中引用的对象

方法区中静态属性引用的对象

方法区中常量引用的对象

本地方法栈中JNI

  • jvm对于引用概念的区分

强引用,类似于Objec o=new Object();只要存在就不会被回收

软引用,弱引用,虚引用。

  • 生存还是死亡

当一个对象想要被回收至少要经理两次标记,如果第一次标志此对象不可达将会被判定需要执行finaliz()方法,如果该对象被一次标记,将会被存入F-QUEUE的队列之中。然后由jvm创建的低优先级的线程去回收。

方法区的回收主要是判定一个常量是否为“废弃常量”,需满足3个条件:

该类所有的实例都已经被回收,java堆不存在任何该类的实例

该类的classloader已经被回收

该类的java.lang.class没有被任何对象所引用,无法通过反射访问到该对象

  • 垃圾回收算法

标记-清除:

标记出所有处于回收状态的对象,然后清除,效率较差

复制算法:

按照容量将内存分为相同的两块大小,每次只使用其中一块,当这一块使用完,将存活对象复制到另一块上面,然后将另一个半区回收。目前主流jvm的回收算法都是采用这种回收算法,但是堆内的内存大多都是朝生夕死,没有必要将空间划分为1:1。所以目前将内存划分为一块较大的Eden空间和两块较小的Survivor空间,每次使用其中Eden和其中一块Servivor空间。Eden和Servivor空间的比例一般为8:1,也就是每次新生代可使用的空间为堆的90%。

标记整理算法

将存活对象移至一端,然后清楚边界之外所有的对象。

分代收集算法

这种思想是按照象生存周期不同的特点,将堆分为新生代,老年代,新生代拥有较多的gc所以采用复制算法,老年代则采用标记整理或者标记清楚算法来回收。

  • 垃圾回收器

serial收集器

serial收集器是最古老,发展历史最悠久的收集器,单线程,而且是新生代收集器的唯一选择。此处单线程的意义不仅仅是使用一个cpu,当它工作时它会暂停jvm所有的线程,进行回收。

parnew收集器

parnew是serial的多线程版本

Parallel Scavenge收集器

吞吐量=运行代码时间/(运行用户代码时间+垃圾回收时间),关注点不同,它是尽可能缩短垃圾手机时用户线程的停顿时间。

-XX:GCTimeRatio 可以用来控制吞吐量

-XX:MaxGCPsuseMills 用来控制jvm最大停顿时间

serial old收集器

serial收集器老年代版本,单线程,标志-整理。

parallel old收集器

parallel scavenge收集器的老年代版本,使用多线程和标志-整理算法。

cms收集器

cms收集器默认启动的线程数是(CXP数量+3)/4

初始标记

并发标记

重新标记

并发清除

初始标记和重新标记仍然需要stop the world,初始标记,仅仅标记gc roots能够关联到的对象,并发标记阶段就是gc roots tracing,重新标记标记因为用户程序产生变动的那部分。

cms收集器的缺点:

a、对于cpu资源敏感,默认启动的线程数是(CXP数量+3)/4,当只有两个cpu时,一半收集线程,一半工作线程,会有效率问题。

b、无法处理浮动垃圾,可能出现Concurrent Mode Failure失败导致一次Full Gc。

浮动垃圾的概念,就是这一次垃圾清除的时候,会产生新的垃圾,但是本次gc无法清除,只能等待下次gc。

c、标记清除,由于采用的是标记清除算法,所以将会产生大量的碎片空间。

-XX:CMSFullGCsBeforeCompaction 设置多少次gc后进行压缩空间

-----------------------------------------------------------------------------------------------------------------------------------------------------------------------

 

                                                

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值