自动内存管理机制

自动内存管理机制

运行时数据区域

运行时数据区域

运行时数据区域

  • 线程私有
  • 程序计数器 Program Counter Register: 属于寄存器,记录当前线程执行指令地址(本地方法为空),通过改变其计数器的值获取下一条执行指令。 内存空间小,每个线程独有一份。因为Java多线程通过切换线程,轮流分配处理器,也就是说在一个时间内只有一条线程在执行,故而需要程序计数器记录之前执行的指令,以保证切换线程后能够恢复到之前执行的位置。

  • 虚拟机栈 VM Stack:线程私有。描述了Java方法执行内存模型。 方法执行内存模型: 每个Java非本地方法调用都会创建一个栈帧,栈帧存储了局部变量表,操作数栈,动态链接,方法出口等信息。 入栈-------------->出栈 调用-->调用中-->调用完成

  • 局部变量表:放有基本数据、引用(reference-对方地址的引用指针)、返回地址(returnAddress指令地址)

  • 本地方法栈 Native Stack:Native方法调用所需的栈。

  • 线程共享
  • 堆 Heap: 所占内存空间最大,也是gc主要区域。 在虚拟机启动时创建,唯一目的只有存放对方实例。几乎所有对象都在堆中。 (1.7-堆可以分为新生代,老年代) 堆空间通过-Xmx -Xms设定(两者相等表示堆空间不会变动)

  • 方法区 Method Area: 加载class文件后,信息保存在方法区中,其中包含类信息、常量、静态常量、符号引用等等 1.7以后Hotspot虚拟机将永久代移出方法区。

  • 运行时常量池: 保存类加载后的字面量和符号应用等。

  • 直接内存: NIO通过管道和缓存可以调用直接内存,从而避免频繁对堆内存的处理,提高性能。 避免虚拟机设定的总内存超出直接内存,从而导致OutOfMemoryError异常。

对象的创建

以new 关键字触对象的创建为例说明(其他有通过反射、子类加载前若父类未加载先加载父类等,类的加载过程,后续补充)

对象的创建

对象内存布局

确定属于哪个类,区别同一个类的实例,并且对象存储的数据和方法。更细致一层包含对象的回收,对象的锁等运行时的信息。

  • 对象头: 自身信息: 哈希码、gc分代、锁、偏向锁等等信息 类型指针:对象指向它的元数据的指针,确定对象是哪个类的实例。 数组大小,只有Java数组需要。

  • 实例数据:字段数据

  • 填充:保证对象的大小必须是8字节的整数倍。

对象的访问定位-reference类型:

  1. 通过句柄访问对象 堆上要维护句柄池,对象改变只需要改变句柄池中的数据
  2. 通过指针访问对象 为对象地址,直接访问对象,一旦对象移动,reference需要改变。-HotSpot VM采用此方式。

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

目的: 1.为了查找和解决内存溢出、内存泄漏等问题 2.为了提高垃圾收集性能。

垃圾收集:

0.垃圾回收什么?

1.什么时候需要垃圾回收?

2.怎么进行垃圾回收?

0.垃圾回收什么?

垃圾回收无用的对象、常量、静态常量甚至加载的类 其中:对象存储在堆中,常量、静态常量、类在方法区中。 即,垃圾回收主要回收堆和方法区中的内存。

  • 如何判断对象无用,或者说‘死’了? 对象到GC Roots对象不可达,之间无引用链。通过可达性算法判断,从GC Roots为根节点,向下搜索,其走过的路径即位引用链。

GC Roots对象 虚拟机栈栈帧中引用的对象、本地方法栈中引用的对象、静态属性引用的对象、常量引用的对象

java虚拟机为了不将暂时不必须的对象一棍子打死,而细分了引用强度。

  1. 强引用: 普遍存在,不回收
  2. 软引用:有用但非必需,在内存即将溢出前进行回收
  3. 弱引用:非必须对象,活到一下次GC发生之前
  4. 虚引用:特点只是在回收时发送一个系统通知

1. 什么时候回收?

安全点-长时间执行的地方(区域块)产生:指令序列复用,如循环跳转,异常跳转、方法调用等 程序执行到安全点,线程主动运行到安全点(通过中断标志,线程轮询标志,将线程中断挂起),再进行回收。

2.如何进行垃圾回收?

方法区内存回收:

永久代:回收无用的类、废弃常量。 废弃常量:没有用的常量 无用的类:所有实例被回收,堆中无其实例;该类的类加载器被卸载回收;在任何地方,该类对应的java.lang。Class对象没有被引用,也无法通过反射访问该类的方法。

堆中内存回收

垃圾回收算法:

  • 分代收集算法:商用虚拟机就堆中对象存活时间不同,而采用不同的回收算法。 新生代:复制算法 老年代:标记-整理算法 或 标记-清除算法。

  • 标记-清除算法: 对可存活的对象进行标记,然后清除未标记的区域。 缺点: 1.容易造成不连续的内存碎片,后期可能找不到空间足够大的连续内存而触发垃圾回收 2.内存区域散乱,标记和清除效率不高。

  • 复制算法: 对半分块,一块内存用完了,将在使用中的对象复制到另一块内存中,把使用的内存全部删掉。 优点:迅速、实现简单,运行高效。 缺点:为了保留可存活对象的存储空间,内存利用率无法达到100%

将新生代分为一个Eden、两个Survivor,默认内存空间大小比是8:1:1。由于新生代对象的回收率高达98%,回收时将eden和一个survivor中存活的对象复制到另外一块survivor区中,再清除之前的内存空间,当其内存空间不够,可依赖老年代空间进行分配担保。

  • 标记-整理算法 对可存活对象进行标记,将标记的对象往一端移动(整理),将端外的内存空间直接清除。
垃圾回收器
非并发收集

单线程:

  • Serial -新生代 复制算法
  • Serial Old -老年代 标记-整理算法
  • 优点:简单高效。单线程,无线程交互切换的开销,高效迅速。JVM Client模式下首选。能与CMS回收器配合使用。
  • 缺点:存在Stop the World,所有线程停顿。一旦回收时间过长,难以接受。

多线程:

  • ParNew-Serial多线程版本,参与与Serial共用,Server模式下首选,因为其能与CMS收集器配合使用。

  • Parallel Scavenge -新生代,复制算法 吞吐量优先,自适应调节策略(系统会收集性能监控信息从而自适应调整GC停顿时间或者最大吞吐量。

  • Parallel Old-老年代,标记-整理算法,能够和Parallel Scavenge 配套使用。

吞吐量 = 用户运行代码时间/CPU总耗时

并发收集

垃圾收集与用户线程同时存在(一边制造垃圾一边回收):

CMS:-老年代 重视服务的响应速度,即要求最短停顿时间。 基于标记-清除算法

  • 运作过程: 初始标记 - Stop the world 简单编辑GC Roots对象, 并发标记 - GC Roots Tracking(可达性分析)过程,用户线程也存在。 重新标记 - Stop the world 修正因并发标记导致的变动,时间比初始标记长,比并发标记短 并发清除 -清除标记的对象,用户线程存在。

  • 优点:低停顿,并发收集。

  • 缺点:

  1. 对cpu资源敏感--收回占用资源,影响服务响应,尤其在低核心的情况下,对cpu占用率较高,并发标记和并发清除的时间较长,影响更大。
  2. 会因为并发清理阶段产生浮动垃圾,内存空间不足的情况下会触发Full GC,出现线程停顿。因CMS并发清理,需要为用户线程预留内存空间,一旦预留空间不出,会出现Concurrent Mode Failure,jvm会临时启用Serial Old收集器进行老年代垃圾回收,从而出现Stop the world所有线程停顿。
  3. 标记-清除算法的缺点,会出现不连续的内存空间,导致出现大对象分配内存的时候触发Full GC。可以设置-XX:CMSFullGCsBeforeCompaction =n 参数,在执行n次不压缩的Full GC后,进行碎片整理(默认该参数为0,即每次Full GC时都进行碎片整理)

G1:

  • 并发收集

  • 分代收集:堆内存没有分为新生代和老年代,将堆分为多个region,所谓的新生代和老年代都是一部分region集合。region有一个与之对应的Remember Set维护,引用的对象处于不同region中(老年代的对象引用了新生代的对象),通过CardTable把相关引用信息记录到被引用对象所属的Region的Remember Set中。

  • 空间整合:不存在大量不连续得碎片。 低停顿,可预测的停顿(可预测时间模型,能够明确指定在M秒的时间内,收集垃圾的时间不得超过N秒)。

  • 运作过程:

  1. 初始标记-线程停顿,时间小
  2. 并发标记-可达性分析找出可存活得对象
  3. 最终标记-将并发中用户线程产生
  4. 塞选回收

转载于:https://my.oschina.net/u/2500836/blog/1536086

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值