JVM 垃圾收集与内存分配
判断对象是否还活着
引用计数法
给对象添加引用计数器,添加加1,引用失效减1,如果为0就是不可使用的。问题是不能解决互相引用带来的问题
可达性分析法
- 以GC Roots为起点,判断到一个对象是否有引用链,就是从开始节点向下能否搜索到,如果搜索不到就是不可达,可以被回收
- GC Roots有以下
- 虚拟机栈中的引用对象
- 方法区中的类静态属性的引用对象
- 方法区中的常量引用对象
本地方法栈是JNI(Native方法)的引用对象
什么是引用
- 就是reference类型中存储的数值代表另外一块内存中的起始地址就称这块内存代表着一个引用(侠义的引用)
- 强引用:类似Object obj=new Object()这类的,垃圾永不回收的引用对象 SoftReference
- 软引用:在内存发生溢出异常前,进行第二次回收的,如果回收后还不足,才会抛出溢出异常
- 弱引用: 能存活到下一次垃圾回收之前,与内存是否足够无关 WeakReference
虚引用:最弱唯一的目的就是在被回收时收到一个系统通知,不能通过引用获取对象和操作影响对象 PhantomReference
消除对象
一个对象至少要经历两次标记:如果不可达进行第一次标记并筛选是否要执行finalize()方法,当对象没有finalize()或被执行过都认为不需要执行。如果判断需要执行会把这个对象放在F-Queue队列中并在稍后虚拟机会以一个底线程去执行,所以这是对象自救的最后一次机会
回收方法区
- 判断一个类是否有用
- 类所有的实例都回收
- 加载类的ClassLoader已回收
- 对应的java.lang.Class对象没有任何地方被引用也无法通过反射访问该类的方法
是否回收类HotSpot虚拟机提供了-Xnoclassgc参数进行控制
垃圾回收算法
标记-清除法
- 标记阶段:慢
清除阶段 :慢,有内存碎片
复制算法
- 把内存一分为二(大小相等)当一块用完了,把存活的复制到另一块上
- 缺点:内存只用了一半:
优化:不分为相等的两部分而是分为Eden Survivor 默认比例8:1,当survivor不够时,老年代来担保,提醒 Survivor 分为From和To 每次复制完互换
标记-整理法
解决复制算法对象存活率高时的问题,先标记-然后让存活的向一端移动,以解新内存碎片的问题
分代收集算法
不同的代用不同的方法,针对性的回收
HotSpot实现
- 可达性分析:
- 因为分析准确所以要产生停顿,为了减少停顿,使用准确式GC ,就是虚拟机知道那些地主存着对象引用,使用OopMap数据结构来达到这个目的,这样GC直接扫描就可以了。
- 为了不产生大量的OopMap,只是在特殊的位置(安全点)记录这些信息,程序到了安全点才会停顿,考虑如果安全点少GC等的时间长,如果多大频繁。
- 在安全点时让所有的线程都到这个点,有两种办法一个是抢断式中断,就是所有的都停下来把那些不在安全点的继续运行到安全点,几乎没有用。另一个是主动式中断,就是打标记当线程到这个标记就自己产生中断(身陷)
- 安全区域
- 安全点不能解决程序没有获取CPU时无法产生中断的问题,以所以产生安全区域,就是此区域任何地方都是安全点
执行到安全区域时,标记进来了,然后发起GC,当要离开时如果没有完成根节点的枚举,等待,收到完成的信号后才可以离开
垃圾收集器
- Serial收集器
- 收集时必需暂停其它的所有线程
- ParNew 收集器
- 就是Serial收集器的多线程版本 控制参数与Serial一样,同样是目前能与CMS老年收集器一起使用的年轻代收集器
- 可以通过-XX:ParallelGCThreads来限制垃圾收集器的线程数
- Parallel Scavenge 收集器
- 并行多线程收集器 它的目标是达到一个可控的吞吐量=运行用户代码的时间/(用户代码时间+垃圾回收的时间)适用后始运逄面不需要太多交互的任务
- -XX:MaxGCPauseMills 垃圾停顿时间 大于0 的毫秒数时间短是以牺牲吞吐量和新生代的空间来换的
- -XX:GCTimeRatio 设置吞吐量大小(0-100)
- -XX:+UseAdaptiveSizePolicy 这是一个是否需要手动设置参数的开关,GC会自适应调整策略,但是要设置一个优化的目标就是上面两个参数
- Serial Old 收集器
- 单线程老年代收集器,使用标记-整理,当CMS收集器失败时使用
- Parallel Old 收集器
- 对应Parallel Scavenge收集器,因为Parallel Scavenge无法与CMS收集器一起工作,让吞吐量优化的收集器可以洛地使用
- CMS 收集器
- 是一种以获取最短停顿时间为目标的收集器 一般的b/s系统 上使用,以和用户线程一起工作
- 4个步骤
初始标记 :要停顿
并发标记
重新标记:要停顿
并发清除 - 缺点:对Cpu非常敏感,会占用用户资源
无法处理浮动垃圾 ,如果失败会产生Full GC ,如果运行内存不足会产生失败并用血腥和的Serial Old 进行回收
产生在碎片,如果空间不够时并提前触发Full GC 提供一个-XX:+UseCMSCompactAtFullCollection默认开,就是进行Full GC时整理内存碎片
-XX:CMSFullGCsBeforeCompaction 执行多少次不压缩整理后,执行一次内存整理,默认是0,每次都执行
- G1 收集器
- 前沿成果,生产环境中没有大量使用
并行与并发 分代收集 空间整合 可预测停顿(看书了解)
GC 日志
- GC , Full GC 停顿类型,如果手动调用System.gc()会产生Full Gc(System)
- [ 前数的数字是代表GC 发生的时间参考是虚拟机启动以来的秒数
- DefNew 新生代发生 ParNew 使用ParNew收集的新生代,PSYoungGen 是Parallel Scavenge对应的新生代
- Tenured 老年代 Perm 永久代 名称也与收集器对应
- a->b(c) d secs a是已使用的,b是已使用的 c是总容量 d 表示该区域GC使用的时间,单位是秒有的会给时更详细的时间
墙钟时间 包含阻塞时间
分配策略
优化分配在Eden上
- -XX:+PrintGCDetails 告诉虚拟机发生垃圾回收果打印回收日志
- Minor GC 新生代GC 频繁 速度快
Major GC/Full GC 老年代 比新生代慢10倍以上
大对象直接进入老年代
- 就是很长的字符串或者数组
- -XX:PretenureSizeThreshold 大于这个参数对象直接在老年代分配,只对Serial 和ParNew收集器有效
- -XX:MaxTenuringThreshold 晋升到老年代年龄设置
- 如果Survivor相同年龄的对象大小占总空间的一半,也直接进行老年代
如果有担保 那么如果空间不足会进行Full GC腾出更多的空间
** 参考深入理解Java虚拟机第三章 **
JVM 垃圾收集与内存分配的更多相关文章
- JVM(十一):内存分配
JVM(十一):内存分配 在前面的章节中,我们花了大量的篇幅去介绍 JVM 内的内存布局.对象在内存中的状态.垃圾回收的算法和具体实现等.今天让我们探讨一下对象是如何分配内存的. 堆内存划分 前面说过 ...
- 深入理解JVM(5)——垃圾收集和内存分配策略
1.垃圾收集对象 垃圾收集主要是针对堆和方法区进行. 程序计数器.虚拟机栈和本地方法栈这三个区域属于线程私有的,只存在于线程的生命周期内,线程结束之后也会消失,因此不需要对这三个区域进行垃圾回收. 哪 ...
- Java Web 深入分析(12) JVM(2) 垃圾收集与内存分配
前言 java的内存分配和垃圾回收往往是影响系统性能和并发能力的主要因素,虚拟机提供许多的参数就是为了根据不同环境和请教下进行调优,没有最好的调优也没有固定的调优.需要我们深入的去了解jvm的各个垃圾 ...
- jvm(2):垃圾收集和内存分配
typora-root-url: ./ 垃圾收集 垃圾收集器关注的是线程共享的这部分内存. jvisualvm用来监控JVM的运行情况,可以用它来查看和浏览Heap Dump.Thread Dump. ...
- JVM读书笔记之垃圾收集与内存分配
1 概述 说起垃圾收集( Garbage Collection , GC ) ,大部分人都把这项技术当做 Java 语言的伴生产物.事实上, GC 的历史远远比 Java 久远,1960 年诞生于 M ...
- JVM学习之内存分配一
转自:http://blog.csdn.net/mazhimazh/article/details/16879055,多谢博主分享 我们知道计算机的基本构成是:运算器.控制器.存储器.输入和输出设备, ...
- JVM探秘:内存分配与回收策略
本系列笔记主要基于<深入理解Java虚拟机:JVM高级特性与最佳实践 第2版>,是这本书的读书笔记. 内存分配一般关注的是对象在堆上分配的情况,对象主要分配在新生代的Eden区中,如果启用 ...
- 深入理解Java虚拟机二:垃圾收集与内存分配
垃圾收集:垃圾收集要完成三件事,包括哪些内存需要回收,什么时候回收及如何回收. 1.需要回收的内存判定:没有引用指向原先分配给某个对象的内存时,则该内存是需要回收的垃圾 Java垃圾收集器在对内存进行 ...
- JVM之---Java内存分配参数(第四篇)
1.内存分配参数---大纲 Ø如何设置堆内存 Ø如何设置栈内存 Ø如何设置方法区 Ø如何设置对的分配比率 Ø设置参数打印堆栈: ØJava程序的两种模式:Server&Client 2.设置堆 ...
随机推荐
- Spring入门教程
Spring新手入门教程,配套下面这两个大神的课程就可以了. 一个是Spring视频教程. 一个是Spring博客教程. https://www.imooc.com/learn/196 http:// ...
- 【linux】【FastDFS】FastDFS上传返回的url直接下载和下载文件的文件名问题
FastDFS安装及其他问题参考:https://www.cnblogs.com/jxd283465/p/11556263.html直接调用FastDFS返回的url,浏览器访问后默认打开方式./us ...
- odoo Botton标签属性详解
按钮属性 1)icon 按钮图标名,可用的按钮图标在 addons/web/static/src/img/下. 2)string 按钮的显示文字 3)type 动作执行类型.可能值是:workflow ...
- [sonarqube的使用] sonarqube安装
一 . SonarQube代码质量检查工具简介 Sonar (SonarQube)是一个开源平台,用于管理源代码的质量 Sonar 不只是一个质量数据报告工具,更是代码质量管理平台 支持Java, C ...
- 新手学习FFmpeg - 调用API完成视频的读取和输出
在写了几个avfilter之后,原本以为对ffmpeg应该算是入门了. 结果今天想对一个视频文件进行转码操作,才发现基本的视频读取,输出都搞不定. 痛定思痛,仔细研究了一下ffmpeg提供的examp ...
- Spring boot 官网学习笔记 - Configuration Class(@import)
推荐使用 Java-based configuration ,也可以使用xml we generally recommend that your primary source be a single ...
- java跬步积累
1.eclipse自动生成get/set方法快捷键 alt+shift+s +r 2.eclipse自动生成等号左边快捷键 将光标移到:号右边,然后按Ctrl+1 3.补全代码快捷键 Alt+/ 4. ...
- 长短时记忆神经网络(LSTM)介绍以及简单应用分析
本文分为四个部分,第一部分简要介绍LSTM的应用现状:第二部分介绍LSTM的发展历史,并引出了受众多学者关注的LSTM变体——门控递归单元(GRU):第三部分介绍LSTM的基本结构,由基本循环神经网络 ...
- php基础——语法、变量
一.php语法: 1.php语言需要写在<?php ?>标签里面 2.php语言每行结束需要使用:作为结束符 3.php是一门弱语言,不要求先声明变量 4.可嵌套在HTML和js语言中 ...
- VR应用评测 - Luna
Luna http://store.steampowered.com/app/605770/Luna/ Steam VR 2017年10月发布 | 开发者:Funomena | 好评率92% 一款制作 ...