深入理解Java虚拟机-第三章GC与内存分配

第三章GC与内存分配

3.1概述

程序计数器、虚拟机栈、本地方法栈3个区域随线程生灭,栈中的栈帧分配多少内存是确定的,因此这几个区域的内存分配具有确定性,内存会随着方法、线程的结束自动回收。
堆和方法区则不同,一个接口中的多个实现类需要的内存可能不一样,一个方法中的多个分支需要的内存可能也不一样,只有程序运行时才知道会创建哪些对象,内存的分配和回收都是动态的。

3.2 如何确定对象存活、死去

3.2.1 引用计数算法

给对象添加一个引用计数器,有一个地方引用他+1,引用失效是-1,任何时刻计数器为0时就不可能再被使用。
缺陷:很难解决对象直接相互循环引用的问题

3.2.2 可达性分析算法

基本思路:从一系列的GC Root对象作为起点,从这些节点开始向下搜素,搜索所走过的路径称为引用链,当一个对象没有任何引用链相连,则对象不可用。
java中可作为gc root的对象
1.虚拟机栈(栈帧中的本地变量表)中引用的对象
2.方法去中类静态属性引用的对象
3.方法区中常量引用的对象
4.本地方法栈中native方法引用的对象

3.2.3 引用

java1.2以前引用的定义:如果reference类型的数据中存储的数值代表的另外一块内存的起始地址,就称这块内存代表着一个引用。
1.2以后扩充为强引用、软引用、弱引用、虚引用;
强引用:只要存在就不会被回收
软引用:在发生内存溢出异常之前,对其进行回收
弱引用:只能活到下次gc
虚引用:不会对生存时间发生影响,设置的目的是在对象被回收时,收到一个系统通知

3.2.4 生存还是死亡

即使是不可达的对象,也并非是非死不可,真正宣告一个对象死亡需要至少两次标记。
第一次标记:将可达性分析时不 可达的对象进行标记,并进行一次筛选(是否有必要进行finalize()方法),将需要执行finalize方法的对象放入F-Queue中。
第二次标记:F-Queue中没有重新关联的对象被二次标记。

3.2.5 回收方法区(Hotspot的永生代)

永生代主要回收两部分内容:废弃常量和无用的类
判断废弃常量和堆中类似。
判断无用的类比较复杂:
1.该类的所有的实例都已经被回收
2.加载该类的classloader已经被回收
3.该类对应的java.lang.class对象没有在任何地方被引用,无法在任何地方通过反射访问该类方法

3.3垃圾回收算法

3.3.1标记-清除算法

分为两个阶段:标记和清除
标记过程为上面的对象标记判定。
有两个不足:
1.效率问题,标记和清除的的小路都不高;
2.空间问题,标记清楚后会产生大量不连续的内存碎片

3.3.2复制算法

内存一分为二,一次只用一半,实现简单,但是浪费太大

3.3.3标记-整理算法

标记过程与标记-清除算法一样,后续步骤不是直接对可回收对象进行清理,而是让所有存活对象移动到一端,然后直接清理边界之外的内存。

3.3.4分代收集算法

根据对象存活周期的不同,将java堆分成新生代和老年代。
新生代使用复制算法
老年代使用标记-清理或标记-整理算法

3.4HotSpot的算法实现

3.4.1枚举根节点

从GCRoot节点找引用链为例,可作为GC Root的节点主要在全局性的引用与执行上下文中,如果逐个查找必定浪费时间。
GC停顿,分析工作必须在一个能确保一致性的快照中执行,一致性是指此时系统看起来像是冻结在某个时间点上,不能出现分析过程中对象引用关系还在不断的变化的情况。
在停顿时,虚拟机需要知道哪些地方存放对象的引用,在HotSpot中,使用一组称为OopMap的数据结构来达到这个目的,在类加载完成的时候,HotSpot就把对象内的偏移量计算出来。

3.4.2安全点

HotSpot没有为每条指令都生成OopMap,只是在特定的位置记录了这些信息,这些位置称为安全点。
对于安全点,如何在GC发生时让所有线程都跑到安全点上再停顿。
1.抢占式中断
在GC发生时,把所有线程都中断,如果线程不在安全点,就恢复线程,让其运行到安全点。
2.主动式中断
当GC需要中断线程的时候,不直接对线程操作,仅仅简单地设置一个标志,各个线程执行时主动轮询这个标志,发现中断标志为真时,就自己中断挂起。

3.4.3安全区域

安全域是指在一段代码片段中,引用关系不会发生变化,在这个区域中的任意地方开始GC都是安全的。

3.5垃圾收集器

G1收集器

特点:①并行与并发②分代收集③空间集合④可预测的停顿
使用G1收集器时,java堆的内存布局就与其他收集器有很大区别,他将整个java堆划分成多个相等的独立区域,虽然保留新生代老年代概念,但不物理隔离,都是region的一部分。
G1跟踪各个region里面的垃圾堆积的价值大小,在后台维护一个优先列表,每次根据允许的收集时间,优先回收价值最大的region
G1收集器中,region之间的对象引用以及其他收集器中的新生代和老年代之间的对象引用,虚拟机都是用remembered set来避免全堆扫描的。G1中每个region都会有一个与之对应的remembered set,当虚拟机发现程序对reference类型的对象进行写操作时,会产生一个write barrier暂时中断写操作,检查reference引用的对象是否在不同的region之中,如果是分代就是检查老年代中的对象是否引用了新生代中的对象,如果引用了,就通过cardtable把相关引用信息记录到被引用对象所属的region的remembered set中。这样就保证gc回收时,不需要扫描全堆就可以不留遗漏。
G1运作步骤:
1.初始标记
2.并发标记
3.最终标记
4.筛选回收

3.6内存分配与回收策略

3.6.1对象优先在eden分配

3.6.2大对象直接进入老年代

3.6.3长期存活的对象进入老年代

3.6.4动态对象年龄判断

如果在survivor空间中相同年龄所有对象大小的总和大于survivor空间的一半,年龄大于等于该年龄的对象就直接进入老年代

3.6.5空间分配担保

在发生MinorGC前,虚拟机会先检查老年代最大可用的连续空间是否大于新生代所有对象总空间,如果成立,那么minorGC可以确保是安全的。如果不成立,查看HandlePromotionFailure设置值是否允许担保失败,如果允许,就继续检查老年代最大可用的连续空间是否大于历次晋升到老年代的平均大小,如果大于,尝试一次minorGC,否则就fullGC

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
后台采用apache服务器下的cgi处理c语言做微信小程后台逻辑的脚本映射。PC端的服务器和客户端都是基于c语言写的。采用mysql数据库进行用户数据和聊天记录的存储。.zip C语言是一种广泛使用的编程语言,它具有高效、灵活、可移植性强等特点,被广泛应用于操作系统、嵌入式系统、数据库、编译器等领域的开发。C语言的基本语法包括变量、数据类型、运算符、控制结构(如if语句、循环语句等)、函数、指针等。下面详细介绍C语言的基本概念和语法。 1. 变量和数据类型 在C语言中,变量用于存储数据,数据类型用于定义变量的类型和范围。C语言支持多种数据类型,包括基本数据类型(如int、float、char等)和复合数据类型(如结构体、联合等)。 2. 运算符 C语言中常用的运算符包括算术运算符(如+、、、/等)、关系运算符(如==、!=、、=、<、<=等)、逻辑运算符(如&&、||、!等)。此外,还有位运算符(如&、|、^等)和指针运算符(如、等)。 3. 控制结构 C语言中常用的控制结构包括if语句、循环语句(如for、while等)和switch语句。通过这些控制结构,可以实现程的分支、循环和多路选择等功能。 4. 函数 函数是C语言中用于封装代码的单元,可以实现代码的复用和模块化。C语言中定义函数使用关键字“void”或返回值类型(如int、float等),并通过“{”和“}”括起来的代码块来实现函数的功能。 5. 指针 指针是C语言中用于存储变量地址的变量。通过指针,可以实现对内存的间接访问和修改。C语言中定义指针使用星号()符号,指向数组、字符串和结构体等数据结构时,还需要注意数组名和字符串常量的特殊性质。 6. 数组和字符串 数组是C语言中用于存储同类型数据的结构,可以通过索引访问和修改数组中的元素。字符串是C语言中用于存储文本数据的特殊类型,通常以字符串常量的形式出现,用双引号("...")括起来,末尾自动添加'\0'字符。 7. 结构体和联合 结构体和联合是C语言中用于存储不同类型数据的复合数据类型。结构体由多个成员组成,每个成员可以是不同的数据类型;联合由多个变量组成,它们共用同一块内存空间。通过结构体和联合,可以实现数据的封装和抽象。 8. 文件操作 C语言中通过文件操作函数(如fopen、fclose、fread、fwrite等)实现对文件的读写操作。文件操作函数通常返回文件指针,用于表示打开的文件。通过文件指针,可以进行文件的定位、读写等操作。 总之,C语言是一种功能强大、灵活高效的编程语言,广泛应用于各种领域。掌握C语言的基本语法和数据结构,可以为编程学习和实践打下坚实的基础。
该资源内项目源码是个人的课程设计、毕业设计,代码都测试ok,都是运行成功后才上传资源,答辩评审平均分达到96分,放心下载使用! ## 项目备注 1、该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的,请放心下载使用! 2、本项目适合计算机相关专业(如计科、人工智能、通信工程、自动化、电子信息等)的在校学生、老师或者企业员工下载学习,也适合小白学习进阶,当然也可作为毕设项目、课程设计、作业、项目初期立项演示等。 3、如果基础还行,也可在此代码基础上进行修改,以实现其他功能,也可用于毕设、课设、作业等。 下载后请首先打开README.md文件(如有),仅供学习参考, 切勿用于商业用途。 该资源内项目源码是个人的课程设计,代码都测试ok,都是运行成功后才上传资源,答辩评审平均分达到96分,放心下载使用! ## 项目备注 1、该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的,请放心下载使用! 2、本项目适合计算机相关专业(如计科、人工智能、通信工程、自动化、电子信息等)的在校学生、老师或者企业员工下载学习,也适合小白学习进阶,当然也可作为毕设项目、课程设计、作业、项目初期立项演示等。 3、如果基础还行,也可在此代码基础上进行修改,以实现其他功能,也可用于毕设、课设、作业等。 下载后请首先打开README.md文件(如有),仅供学习参考, 切勿用于商业用途。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值