方法区:

1.线程共享
2.储存类信息,常量,静态变量,编译器编译后的代码
3.非堆(别名)用于区分Java堆
4.不需要连续的内存
5.可以固定或可扩张
6.选择不实现垃圾回收//这个区域很少进行垃圾回收
7.针对常量池回收
8.对类型的卸载
9.无法满足内存分配需求抛出OutOfMemoryError4

虚拟机栈(VM Stack):

1.线程私有
2.生命周期和线程相同
3.描述Java方法执行的内存模型(每个方法执行会创建一个栈帧)
4.栈帧
5.线程请求深度大于虚拟机允许深度抛出StackOverFlowError
6.扩展无法申请到足够内存抛出OutOfMemoryError

本地方法栈(Native Method Stack):

1.为本地方法服务
2.区别于虚拟机栈: 为虚拟机执行Java方法服务
3.抛出StackOverFlowError, OutOfMemoryError

Heap:

1.Java虚拟机所管理最大一片内存区域
2.线程共享
3.虚拟机启动时创建
4.存放对象实例,数组
5.垃圾回收管理GC主要区: 收集器采用分代收集算法,
6.可划分出多个线程私有的分配缓冲区(Thread Local Allocation Buffer TLAB)
7.物理逻辑不连续,逻辑顺序连续即可
8.可通过-Xmx和-Xms控制大小
9.堆无法扩展时抛出OutOfMemoryError

程序计数器:

1.较小内存空间
2.当前线程行号指示器
3.线程私有内存
4.唯一个没有OutOfMemoryError区域

直接内存:

1.NIO中使用Channel,Buffer的IO方法,使用Native函数库直接分配的堆外内存
2.会抛出OutOfMemoryError

对象创建:

1.类加载检查机制
2.为新生对象分配内存
3.把一块确定大小的内存从堆中划分出来:
4.将分配的空间初始化为0(不包含对象头)
5.对对象进行必要设置
6.属于哪个类的实例
7.如何找到类的元数据信息
8.对象的哈希值
9.对象的GC分代年龄
10.这些数据存放在对象头(Object Header)中
11.对象得到创建,但是所有字段为0,在执行new之后立即执行方法

对象的内存布局:

1.对象(Object Header):存储对象自身运行时数据(Mark Word):哈希码,GC分代年龄,锁状态标识,线程持有锁,偏向线程ID,偏向时间戳
2.类型指针:对象指向它的类元数据的指针—虚拟机通过该指针确定该对象属于哪个类; 不是所有的对象实例都保留有类型指针; 如果对象是数组,还必须有一块用于记录数组长度的数据
3.实例数据(Instance Data)真正存储的数据: 储存顺序受到虚拟机分配策略参数(Fields Allocation Style)和字段在Java源代码中定义顺序的影响
4.对齐填充(Padding):仅起占位作用

对象访问定位

Java通过栈上引用(reference)数据来操作堆上具体对象
句柄访问:
1.堆中划分一块内存作为句柄池
2.reference中存储对象的句柄地址
3.句柄中包含对象实例数据与类型数据各自的具体地址信息
优点:reference中存储稳定的句柄地址,在对象移动时只会改变句柄中的实例数据指针

GC算法

早期GC算法:
引用计数法:对象获得一个引用计数器,有地方引用,则记数器+一次,当计数器为0表示对象不被引用,垃圾回收器进行回收过程; 但是无法解决对象之间循环引用
例: A obj1=new A();B obj2=new A();
obj1.a=obj2;obj2.a=obj1;obj1=null;obj2=null;
java采用可达性分析算法:
当对象到GC Roots没有任何引用连接的时候,此对象是死缓状态,被进行标记,若该对象没有覆盖finalize()/该方法已被调用过,则此对象在第二次被标记的时候移出回收集合,发生回收
引用------
强引用:强引用存在就不会被GC
软引用:有用单非必须的对象,程序发生OOM之间进行二次回收,如果二次回收没有足够的内存,抛出OOM
弱引用:只能活到GC之前,GC时候无论内存够不够,都会被回收
虚引用:用于引用关联对象被GC时会收到一个系统通知

回收方法区:
1.废弃常量:常量池中一个常量没有引用指向,GC时将会被内存回收
2.无用类:该类所有实例被回收,加载该类的ClassLoader被回收,Class对象没有地方引用,不能通过反射访问该类

GC算法:
1.标记清除算法:首先标记对象,GC时进行清除; 缺点:产生大量不连续的内存空间碎片
2.复制算法: 将内存划分为大小相等的两块内容,每次只使用其中的一块,每次GC时将该内存上的对象移动到另一块内存上,对使用过的空间进行清除
改进措施–新生代更新速度快,内存划分比例不是1:1,按一大一小处理
3.标记整理算法:所有存活的对象往内存的一段移动,清理边界的对象
4.(最常用)分代收集算法:根据对象生存周期不同将内存划分为新生代(大量对象死去,存活率低,复制算法),老生代(对象存活率高,标记清除),根据每块区域的不同使用合适的算法

HotSpot(热区)

可达性分析:
1.枚举根节点(线程必须停顿,即使CMS收集器),逐一枚举GC Roots节点引用链上节点必然不可能,大多数采用OopMap根据对象地址偏移量计算其位置或者JIT编译过程中,将特定位置记录放入栈/寄存器中
2.GC停顿:分析期间为保证分析的准确性,引用不能变化,GC时必须暂停所有Java执行线程
3.OopMap系统停顿时,不需要检查所有执行上下文及全文引用位置,而使用OoMap; 类加载完成时,HotSpot会记录偏移量上的类型供GC扫描
4.SafePoint(安全点,在特定位置停住执行GC):程序并非在所有位置都停顿下来进行GC, 只有达到SafePoint时才停顿; SafePoint不能太少导致GC等待时间过长, SafePoint不能太多导致GC花费更多内存; 选取标准:是否让程序长时间执行的特征; 例如:方法跳转,调用,异常跳转导致产生SafePoint
5.抢断式中断:首先所有的线程中断,若线程中断的地方不再SafePoint上恢复,让它跑到SafePoint上; 没有虚拟机采用此做法
6.主动式中断:GC是需要中断线程,不直接对线程操作,而是设置一个标志,各个线程主动轮询这个标志,发现标志为真,则自己中断挂起//单个线程在标志上不断轮询,为真,挂起
7.SafeRegion(SafePoint的扩展):一段代码片段中,引用关系不会发生变化,在这个区域中任意地方开始GC都是安全的//比如在线程sleep,blocked的状态下,程序无法响应JVM中断请求

垃圾回收器具体实现:

并行:多个垃圾回收器线程同时运行,但用户线程暂停
并发:垃圾回收器和用户线程同时运行,但在不同CPU上处理

  1. Serial收集器(标记整理算法):最初的收集器; 新生代收集器; 单线程收集器; Client模式下首选;//简单高效没有线程交互开销

  2. ParNew收集器: Serial的多线程版; Server模式下首选,和CMS搭配

3.Parallel Scavenge收集器(复制算法): 新生代收集器; 并行多线程收集器;
用于达到可控的吞吐量, 而不是关注用户缩短线程的暂停时间;意义在于高效率使用CPU,适合于后台运算,不需要太多的交互任务
吞吐量=运行用户代码时间/(运行用户代码时间+垃圾收集时间); 精准控制吞吐量参数;
控制最大垃圾收集停顿时间,设置最小时间并不能使系统垃圾收集变快(设置时间:-XX:MaxGCPauseMillis;设置吞吐量:-XX:GCTimeRatio);
GC自动适应调整策略:根据当前系统运行情况收集性能监控信息,动态调整新生代大小,Eden与Survivor区比例大小,老年代对象年龄等参数,无需手工设置,提供最合适的停顿时间或者最大的吞吐量(-XX:+UseAdaptiveSizePolicy)
注:不能和CMS搭配

Serial Old收集器
1.Serial老年代版本
2.单线程收集器
3.使用标记整理算法
4.主要是Client端虚拟机使用
5.如果Server模式下,主要用于—JDK1.5以前配合Parallel Scavenge使用; 作为CMS的后备预案,在并发收集发生Concurrent Mode Failure时使用

Parallel Old收集器
1.Parallel Scavenge收集器的老年代版本
2.多线程收集器
3.使用标记整理算法

CMS(Concurrent Mark Sweep//并发标记清理)大多数集中在B/S架构
1.获取最短回收停顿时间为目标
2.使用标记清理算法
3.运作过程如下—
–初始标记(CMS inital mark):标记GC Roots能直接关联到的对象,速度快
–并发标记(CMS Concurrent Mark):进行GC Roots Tracing的过程
–重新标记(CMS remark):修正并发标记期间因用户程序继续运作而导致标记产生变动的那一部分对象的标记记录,比如初始化标记稍长,但远比并发标记时间短
–并发清除(CMS Concurrent Sweep)
4.CMS收集器的内存回收过程是与用户并发执行的
5.CMS明显的缺点:
–CPU大于4个,CMS回收垃圾线程随CPU数量的增加而减少; 当CPU数量少于4个, CMS对用户程序的影响变得很大
–增量式并发收集器(Incremental Concurrent Mark Sweep/i-CMS)效果一般,不推荐使用
–无法处理浮动垃圾,Concurrent Mode Failure会导致另一次Full GC生产而只能将这部分回收失败的垃圾留在下次GC再清理,因此CMS必须预留一部分空间提供给并发收集时的程序使用
6.JDK1.5默认设置老年代使用86%后激活CMS收集器,若老年代增长不是太快,可以提高参数(-XX:CMSInitiatingOccupancyFraction)触发百分比; JDK1.6,CMS启动阀值已经提高到92%
7.如果运行期间预留的内存不够CMS,会出现Concurrent Mode Failure, 此时启动后备预案:临时启动Serial Old收集器重新进行老年代垃圾收集,但会导致停顿时间很长;因此提高触发百分比参数容易导致性能降低
8.标记算法容易产生很多内存碎片
9.CMS提供一个-XX:UseCMSCompactAtFullCollection开关参数,默认开启,用于CMS收集器顶不住Full GC时,开启内存碎片化整理过程,此过程无法并发,停顿时间较长
10.JVM提供-XX:CMSFullGCsBeforeCompaction,用于设置执行多少次不压缩Full GC后进行一次压缩的Full GC(默认为0,表示每次进入Full GC时进行碎片化处理)

G1收集器(标记整理算法):
1.面向服务端应用
2.并行,并发
3.分代收集:将Java堆划分为多个大小相等独立区域(Region),新生代和老生代依旧存在,属于Region的集合
4.空间整理
5.可预测的停顿:
–使用Remembered Set来避免在整个Java堆中进行全区域的垃圾收集
–G1跟踪收集各个垃圾堆积的价值大小(回收所获得的空间及回收所需的时间),后台维护一个优先级列表
–每次根据允许的收集时间,优先回收价值最大的Region(Carbage-First)
6.G1收集器运作大致可划分为一下步骤:
–初始化标记(Initial Marking)
–并发标记(Concurrent Marking)
–最终标记(Final Marking)
–筛选标记(Live Data Counting and Evacuation)

理解GC日志:

例:33.125:[GC [DefNew: 3324K->152K(3712K),0.0025925 secs] 3324K->152K(11904K) 0.0031680 secs]
100.667:[Full GC [Tenured: 0K->210K(10240K),0.0149142 secs]4603K->210K(19456K),[Perm : 2999K->2999K(21248K)],0.0150007 secs][Times:user=0.01 sys=0.00,real=0.02 secs]
1.33.125:/100.667:表示GC发生时间
2."[GC,[Full GC":此次垃圾收集的停顿类型,不能用于区分新生代/老生代GC;Full表示发生停顿
3."[DefNew ,[Tenured ,[Perm":表示GC发生的区域,DefNew(收集器的新生代), ParNew(收集器老生代)
4.“3324K->152K(3712K)”:GC前内存使用量->GC后内存使用量(给内存区域总容量)
5."3324K->152K(11904K):GC前堆已使用量->GC后堆使用量(堆总容量)
6.“0.0031680secs”:内存区域GC所占用的时间
7.[Times:user=0.01,sys=0.00,real=0.02secs]:指用户,内核,操作开始到结束所花的时间

内存回收与分配策略

对象内存分配:
1.堆:大多数分配在堆上的Eden新生代区,TLAB//如果启动本地线程分配缓冲,优先在TLAB上分配,Tenured//直接分配到老年代中
2.栈:JIT编译
注:大对象直接进入老年代, 长期存活的对象进入老年代
动态对象年龄判断:
1.当Survivor中的相同年龄的所有对象的大小总和大于Survivor的一半时,年龄大或者等于该年龄的对象可以直接进入老年代,不用等到MaxTenuredThresold设置的值

空间分配担保:

1.在Minor GC之前,JVM会检查老年代的连续内存空间够不够新生代所有对象的内存空间, 够–Minor GC是安全的, 不够–JVM会查看HandlePromotionFailure设置值是否允许担保失败:大于(尝试进行Minor GC,尽管Minor GC是有风险的),小于(HandlePromotionFailure设置不允许冒险,会进行一次Full GC),允许(继续检查老年代的最大可用连续空间是否大于历次晋升到老年代对象的平均水平)
"冒险"的概念:
1.大量的对象在Minor GC后仍然存活,需要老年代进行分配担保
2.把Survivor无法容纳的对象直接进入老年代
3.进行这样的担保,首先保证老年代空间足够容纳这些对象
4.对象多少能够存活下来再实际完成内存回收之前无法确定,所以按照以前晋升老年代对象容量的品均值作为参考
5.不够,再确定是否需要进行Full GC来腾出更多的空间

JVM垃圾收集器与内存分配策略学习总结相关推荐

  1. jvm垃圾收集器与内存分配策略

    2019独角兽企业重金招聘Python工程师标准>>> 垃圾收集器与内存分配策略: 以下参考周志明的<<深入理解jvm高级特性与最佳实践>>. 判断对象是否存 ...

  2. JVM:垃圾收集器与内存分配策略

    垃圾收集器与内存分配策略 1.对象已死吗 1).引用计数算法 引用计数算法:给对象中添加一个引用计数器,每当有一个地方引用它时,计数器值就加1:当引用失效时,计数器值就减1:任何时刻计数器为0的对象就 ...

  3. java eden分配参数,JVM垃圾收集器与内存分配策略,

    垃圾收集器与内存分配策略 对象存活判断 引用计数算法 给对象添加一个计数器,每有一个引用+1,当引用失效-1,若为0则不在被使用. 可达性分析算法 对象是否可到达GC roots 或者说GC root ...

  4. [JVM] 垃圾收集器与内存分配策略

    目录 简介 哪些内存需要回收 引用计数算法 可达性分析 再次谈引用 生存和死亡 简介 GC(Carbage Coolection),需要完成的3件事情 : 哪些内存需要回收 什么时候回收 如何回收 程 ...

  5. jvm(3)-垃圾收集器与内存分配策略

    [0]README 0.1)本文部分文字转自:深入理解jvm,旨在学习 垃圾收集器与内存分配策略 的基础知识: [1]垃圾回收概述 1)GC(Garbage Collection)需要完成的3件事情: ...

  6. 【深入理解Java虚拟机学习笔记】第三章 垃圾收集器与内存分配策略

    最近想好好复习一下java虚拟机,我想通过深读 [理解Java虚拟机 jvm 高级特性与最佳实践] (作者 周志明) 并且通过写一些博客总结来将该书读薄读透,这里文章内容仅仅是个人阅读后简短总结,加强 ...

  7. 《深入理解JAVA虚拟机》学习日志----一、自动内存管理机制(2.垃圾收集器与内存分配策略)

    二.垃圾收集器与内存分配策略 前言:讨论的区域集中在Java堆和方法区中,而其他几个区域的内存分配和回收都具备确定性,所以不需过多考虑回收 的问题,因为方法结束或者线程结束时,内存自然就跟随着回收了. ...

  8. 垃圾收集器与内存分配策略(五)之垃圾日志与常见参数

    2019独角兽企业重金招聘Python工程师标准>>> 垃圾收集器与内存分配策略(五)--垃圾日志与常见参数 理解GC日志 每个收集器的日志格式都可以不一样,但各个每个收集器的日志都 ...

  9. java_opts gc回收器_jvm垃圾收集器与内存分配策略

    垃圾收集器与内存分配策略: 以下参考周志明的<>. 判断对象是否存活: 引用计数:通过判断对象被引用的次数(为0,则表示不可被使用),但这很难解决对象相互循环引用的问题. 根搜索算法:即采 ...

最新文章

  1. 防止SQL注入式攻击
  2. 如何删除输入文本元素上的边框突出显示
  3. Entity Freamwork 6连接PostgreSql数据库
  4. ashx session 使用注意要点。
  5. inet_ntop函数和inet_pton函数
  6. 【机器学习】岭回归(L2正则在干嘛!)
  7. java setrotation_如何使用Java库将文档转换为横向模式?
  8. 浅析 Linux 初始化 init 系统,第 3 部分: Systemd
  9. leetcode942. DI String Match
  10. 定性和定量大数据分析方法指南
  11. JavaWeb项目打包上线简单流程
  12. 数据库设计——概念模型
  13. 解决最近github网页无法打开问题
  14. 技术领导力:作为技术团队领导经常为人所忽略的技能和职责
  15. 玉柴spn码故障对照表_玉柴电控柴油机故障代码及读码方法2
  16. c语言中常用数学符号,C语言中常用的数学公式
  17. 一本正经的聊聊手机主题颜色随手机壳颜色变化的几种方案
  18. AI聊天机器人接口制作php,使用图灵api创建微信聊天机器人_php技巧
  19. 2020最新ubuntu 18 安装emqttd(emqx)
  20. 获取一个字符串的拼音码

热门文章

  1. 预防死锁可以破坏哪些死锁的必要条件
  2. win10怎么设置默认输入法_win10系统输入法失效打不了字怎么办
  3. 概率论与数理统计思维导图知识框架_考研概率论与数理统计 综合题型秘籍思维导图① 随机变量1~3章 [21考研上岸之旅]...
  4. pymysql操作mysql数据库
  5. 解决python中html 代码被注释掉 依旧被解释导致报错ERROR:tornado.access:500 GET /home (xxx.xxx.xxx.xxx)
  6. Day07-函数(2)
  7. Zookeeper的简介及命令行操作
  8. Exception in thread main java.lang.UnsupportedClassVersionError的另类解决办法
  9. 服务器定期监控数据_基础设施硬件监控探索与实践
  10. ARM中ROM,RAM,FLASH区别