1. 垃圾回收器

职责

分配内存

保证有引用对象不被回收

保证无引用对象被回收

设计方式

串行(Serial)与并行(Parallel)

串行的回收方式, 每次只能执行一种操作. 例如, 在多 cpu 的情况下, 只能有一个 cpu 来执行回收.

而并行则可以将回收任务分为多部分交给不同的 cpu 同时执行.  并行的方式速度更快,

但是会牺牲一些额外的复杂度和造成一些潜在的内存碎片

Concurrent vs Stop-the-world

Stop-the-world 的方式回收垃圾, 会使得程序的执行完全被挂起, 知道回收完成. 而 Concurrent

的方式则可以让垃圾回收任务与程序同时运行.Concurrent 只有小部分情况下会有短暂的 stop-the-world 的行为. Stop-the-world

的垃圾回收则比 Concurrent 更简单, 因为此时堆空间是静止的, 里面的对象不会发生改变. 而 Concurrent 的暂停时间会更短,

但是堆内对象在垃圾回收时还会更新, 所以他会有额外的性能开销, 并且需要更大的堆空间

压缩(Compacting) vs 非压缩(Non-compacting) vs

复制(Copying)

采用压缩的方式, 在垃圾回收期决定了哪些对象是存活的, 哪些是垃圾以后, 他会将存活都放在一起, 让后回收垃圾对象.

这样在下次分配内存空间的时候会更高效.

而非压缩的方式, 则是将垃圾对象原地释放(并不会移动存活的对象来创造连续的内存空间). 他的优点是回收速度更快, 但是会造成内存碎片,

使得分配内存的代价更大, 因为在分配的时候需要去搜索堆空间找到一块大内存来容纳一个大的对象.

复制回收器则会将存活对象都复制到一块新的空间, 优点是源内存空间可以被视为是空的, 回收更快, 缺点是需要额外的内存空间.

性能指标

吞吐量(Throughput) - 非垃圾回收时间占总时间百分比

垃圾回收开销(Garbage collection overhead) - 与吞吐量相反, 垃圾回收时间占总时间百分比

暂停时间(Pause time) - 垃圾回收期间程序暂停的时间

回收频率(Frequency of collection) - 垃圾回收频率

资源占用(Footprint) - 参数的大小, 例如堆大小

即时性(Promptness) - 对象变为垃圾到这块内存变为可用的时间

对于交互式程序来说, 更重要的是低暂停时间, 而非交互式程序则更关心总的垃圾回收时间.

2. J2SE 5.0 HotSpot JVM 的垃圾回收器

HotSpot 的分代机制

HotSpot JVM 中的内存被分为三代: young generation, old generation, permanent

generation. 绝大部分对象的初始化都在 young 区. Old 则包含多次年轻代垃圾回收后存活下来的对象, 也包括一些无法分配到 young

中的大对象, 他们会被直接分配到 old. Permanent 则是包括一些 JVM 需要查找的便利信息, 例如对象类方法描述信息.

Young 由 Eden 和两个 Survivor 组成, 如图所示. 绝大部分对象在 Eden 初始化, 部分大对象会直接分配到年老代.

Survivor 用来保存在 young 垃圾回收后存活下来的对象. 任何时候, survivor 区都是一个保存了上述的存活对象(标记为 From),

一个是空的, 空的留作下次回收时使用.

垃圾回收类型

每当 young 满了,  会进行一次 young generation collection (又叫 minor collection),

这次回收只针对 young 区. 每当 old 或者 permanent 满了, 会进行一次 full collection (又叫 major

collection). 这次回收会对所有代进行回收. 一般来说, young 回收首先发生, 它使用专门对 young 设计的算法, 这个算法对 young

区最高效. 然后会使用 old 区回收算法对 old 和 permanent 进行回收. 而如果有压缩, 则每个代都会分别进行压缩.

有时候 old 区会因为数据太多造成放不下从 survivor 传过来的对象, 这时候, 除了 CMS 回收器以外, 会发生一次使用 old

回收算法对整个堆的回收. (CMS old 区回收算法是特殊情况, 它无法对 young 区进行回收)

快速内存分配

从大块的内存中分配空间效率是非常高的, 因为它使用了 bump-the-pointer 技术. 因为它会使用指针一直追踪最后一次内存分配的对象,

当新的分配发生时, 只需要检查剩余的内存是否足够, 然后移动指针并初始化对象.

对于多线程程序, 分配操作必须保证线程安全, 而使用全局锁则会造成性能瓶颈. HotSpot JVM 使用了一个叫做 Thread-Local

Allocation Buffers (TLABs) 的技术. 它通过给每个线程分配自己的线程缓存来提高内存分配效率. 由于他们可以从自己的缓存中分配内存,

所以不需要全局锁, 配合 bump-the-pointer 技术则可以很快的分配内存. 只有在 TLAB 满了的时候,

需要申请更多的空间的时候才需要全局锁.

串行回收器

使用串行回收器, young 和 old 的回收会使用单个 cpu 并用 stop-the-world 的方式串行执行.

1) Young 区的串行回收

下图是 young 区回收示意图. Eden 中的存活对象会被复制到标记为 To 的 Survivor 区 (除了那些过大的对象, 会被直接复制到 Old

区). 同样, 标记为 From 的 Survivor 区的存活对象也会被复制到 To 区, 而 From 中足够老的对象则会复制到 Old 区.

如果 To 区已经满了, Eden 和 From 中还存活的对象则会直接复制到 Old 区. 在复制完成以后, 那些留在 Eden 和 From

中没有被复制的对象都会被标记为垃圾.

当 young 回收完成后, Eden 和原来的 From 都会被清空, 只有原来的 To 会存在存活的对象. 然后 From 和 To 会相互交换角色

(From 变成 To, To 变成 From). 如图

2) Old 区的串行回收

Old 区的串行回收使用 mark-sweep-compact 算法. Mark 阶段, 回收器标记所有存活的对象. Sweep 阶段,

回收器扫描所有代, 并识别出哪些是垃圾. 最后回收器会进行滑动压缩 (sliding compaction), 将存活对象都压缩到 old 区的起始端,

将空闲空间留在相反的一端. 这样在下次分配内存的时候就可以使用 bump-the-pointer 技术快速分配了. 如图

3) 什么时候使用串行回收

串行回收一般用于对暂停时间需求不高的客户端机器. 目前的硬件条件, 大部分64MB堆空间的程序可以再半秒左右的时间完成一次 full

collection. (注: 文章写于 2008 年)

4) 启用串行回收器

串行回收器在非服务端机器上默认启用, 也可以通过参数 -XX:+UseSerialGC 启用.

并行回收器

To be continued

原文:http://www.cnblogs.com/zemliu/p/3776797.html

java内存管理白皮书_Java 内存管理白皮书相关推荐

  1. java内存区域与内存溢出异常_Java内存区域与内存溢出异常

    Java的内存管理是一个老生常谈的问题,虽然Java号称可以自动管理自己的内存,使程序员从内存管理的围墙解放出来,但是一连串的内存泄漏和溢出方面的问题,使得我们不得不去深入了解Java的内存管理机制. ...

  2. java 鸡兔统统_Java内存泄露介绍

    Java的最显着的优点之一是其内存管理.您只需创建对象,并且Java Garbage Collector负责分配和释放内存.但是,情况并不那么简单,因为Java应用程序中经常发生内存泄漏. 本教程将说 ...

  3. java 内存详解_Java内存详解

    一.了解java的内存大致划分 栈:存放基本类型的数据和对象的引用,但对象本身不存放在栈中,而是存放在堆中. 堆:存放用new产生的数据 静态域:存放在对象中用static定义的静态成员 常量池:存放 ...

  4. java double储存原理_Java内存分配原理

    Java内存分配与管理是Java的核心技术之一,一般Java在内存分配时会涉及到以下区域: ◆寄存器:我们在程序中无法控制 ◆栈:存放基本类型的数据和对象的引用,但对象本身不存放在栈中,而是存放在堆中 ...

  5. java内存模型 原子性_Java内存模型JMM 高并发原子性可见性有序性简介 多线程中篇(十)...

    JVM运行时内存结构回顾 在JVM相关的介绍中,有说到JAVA运行时的内存结构,简单回顾下 整体结构如下图所示,大致分为五大块 而对于方法区中的数据,是属于所有线程共享的数据结构 而对于虚拟机栈中数据 ...

  6. java内存分析工具_java内存查看与分析

    业界有很多强大的java profile的工具,比如Jporfiler,yourkit,这些收费的东西我就不想说了,想说的是,其实java自己就提供了很多内存监控的小工具,下面列举的工具只是一小部分, ...

  7. java 内存屏障类型_Java内存模型精讲

    1.JAVA 的并发模型 共享内存模型 在共享内存的并发模型里面,线程之间共享程序的公共状态,线程之间通过读写内存中公共状态来进行隐式通信 该内存指的是主内存,实际上是物理内存的一小部分 2.JAVA ...

  8. java和硬件交互_Java内存模型

    Java内存模型 我们常说的JVM内存模式指的是JVM的内存分区:而Java内存模式是一种虚拟机规范,真实并不存在 Java虚拟机规范中定义了Java内存模型(Java Memory Model,JM ...

  9. java 溢出与泄露_Java内存溢出与栈溢出

    一.背景知识 1.JVM体系结构 2.JVM运行时数据区 3.JVM内存模型 JVM运行时内存 = 共享内存区 + 线程内存区 3-1.共享内存区 共享内存区 = 持久带 + 堆 持久带 = 方法区 ...

  10. eclipse占用内存过大_Java内存泄漏分析工具Memory Analyzer Tool

    一个大型的Java项目也许从开发到测试结束并可能不能未发现一些重大的问题,但是在生产环境中还是会出现一些非常棘手的问题,如内存泄漏直接导致服务宕机,遇到这样的问题对于一个经验尚浅的开发人员来说难度非常 ...

最新文章

  1. 2021-02-23 如何用简单易懂的例子解释条件随机场(CRF)模型?它和HMM有什么区别?从HMM、MEMM、CRF某牛自己总结的
  2. android 学习笔记(八)building system8.5 shell脚本的学习
  3. 使用随机数以及扩容表进行join代码
  4. 【AI白身境】学深度学习你不得不知的爬虫基础
  5. P2754 [CTSC1999]家园
  6. TensorFlow学习笔记(九)tf搭建神经网络基本流程
  7. 在 Redis 上实现的分布式锁
  8. vivo21a点击android版本,VIVO X21A原厂线刷救砖包_内附工具可救砖
  9. 【数据结构】NOJ016—计算二叉树叶子结点数目
  10. 题目 1341. 十三号星期五
  11. 清卡时提示“增值税未申报或未比对”
  12. 计算机调节音量找不到,电脑右下角的小喇叭不见了?教你这样操作,轻松调节音量!...
  13. 史上最全的英语连读规则一网打尽
  14. 一道CF送命题引发的博文
  15. 【Django | allauth】登录_注册_邮箱验证_密码邮箱重置
  16. 图片转成base64格式上传至数据库
  17. 恢复系统自带的office软件
  18. The error may involve defaultParameterMap ### The error occurred while setting paramete
  19. 淘宝/天猫获取卖出的商品订单列表API接口,店铺订单API接口,店铺订单详情API接口
  20. 编程的各种骚操作(一)

热门文章

  1. 【Shiro权限管理】5. Shiro权限URL 配置细节
  2. 【学习摘记】马士兵bbs改良版_课时37_搜索与最后残留问题解决
  3. 深度残差网络:ResNet
  4. 2023年全国最新高校辅导员精选真题及答案28
  5. unity dots_宣布DOTS的Unity和Havok物理
  6. 玩电脑,还是被电脑玩
  7. CSS :has伪类
  8. 3分钟理解np.meshgrid()
  9. linux chmod 755的含义
  10. 数据库管理系统的分类