参考的优秀文章

前言

本文是《深入理解Java虚拟机 JVM高级特性与最佳实线》(机械工业出版社)的读书笔记,记录阅读后的部分理解。推荐这本书,深入浅出讲解了Java虚拟机的知识。

疑问及解答

Java运行时有哪几个常用的内存空间?

  • PC寄存器
  • Java虚拟机栈
  • 本地方法栈
  • Java堆
  • 方法区

PC寄存器

PC为Program Counter的意思,用于记录代码执行的位置。Java是支持多线程的,同时可能有多处代码同时执行,每个线程都需记录各自代码执行的位置,因此,PC寄存器是线程私有的。

用栈来存储什么信息?

Java栈是执行方法时用来存放方法执行所需的信息。一个方法的信息存放为一个栈帧(栈的元素)。一个栈帧包含一个方法所需的信息,包括属性,如8大基本类型、引用类型(栈中只存放引用,实际的对象存放在堆中,后面介绍)和返回地址。

为什么使用栈的数据结构来存储?

因为栈的后进先出特性与方法调用的生命周期特性相吻合。看下图,会让你有所启示。

sequenceDiagram
1方法->>2方法: 调用2方法,入栈(先入栈)
2方法->>3方法: 调用3方法,入栈(后入栈)
3方法->>2方法: 3方法执行完毕,出栈(先出栈)
2方法->>1方法: 2方法执行完毕,出栈(后出栈)

堆空间分布的宏观了解

堆的空间分为:

  • 新生代区。主要存放新生代的对象,又可以进一步分为Eden、From Survivor、To Survivor,区如其名,Eden意为“伊甸园”,Survivor意为“幸存者”,他们存放的对象特点相信大家通过其名称能够理解。对象优先在伊甸园分配,对象熬过了一次Minor GC后,可移到幸存区,对象的年龄(age)会加1。
  • 老年代区。一般情况下存放长期存活的对象。
  • 永久代区。用来存放类信息,想想方法区。

有哪些内存回收算法,及其特点

  • 标记-清除算法。标记垃圾对象,然后统一清除。这个算法一个明显的缺点是会造成内存空间不连续。一般用在老年代区。
  • 标记-整理算法。标记垃圾对象,然后整理内存空间,整理出连续的内存空间。此算法为标记-清除算法的优化。一般用在老年代区。
  • 复制算法。将内存中存活对象复制到To survivor区,然后清空该空间,这样就获得了一块连续的内存空间。鉴于此算法的特点,它不适用于存活对象较多的内存空间,所以一般用在新生代区中。

To survivor与From survivor的区别

使用复制算法对新生代区垃圾回收时,首先将Eden中存活对象复制到To survivor(To survivor此时应该是空的),将From survivor超过年龄阀值的对象复制到老年代区,其他未到年龄的存活对象复制到To survivor,然后清空Eden和From survivor空间,这样就得到了连续可用的内存空间了。然后,From survivor和To survivor对换,这样,From survivor装的是幸存对象,To survivor是空的。

附:

  • Eden与Survivor的空间比例默认是8:1,此比例可通过“-XX:SurvivorRatio”参数设置。
  • 对象优先分配到Eden(Eden是“伊甸园”的意思,而伊甸园是人类诞生的地儿),熬过一次Minor GC后,对象被移动到Survivor,对象的年龄加1,到达一定年龄阀值可晋升老年代。年龄阀值可通过“-XX:MaxTenuringThreshold”参数配置。
  • 复制算法一般适用于新生代区的Minor GC,将存活对象复制到To survivor时,如果存活对象较多较大,会出现To survivor空间不足的情况,需要老年代区作担保,所谓担保,就是由老年代区装这些溢出的对象。极端情况下,连老年代区也有可能不够空间,有一个参数“-XX:-HandlePromotionFailure”设置是否允许担保失败。Minor GC前,如果老年代区的空间大于新生代区,则Minor GC是无空间风险的,可以直接进行Minor GC;否则查看参数是否允许担保失败,如果允许,并且老年代区最大可用空间大于历次晋升到老年代区对象的平均大小,则Minor GC;如果不允许,则进行Full GC。

【Java】关于JVM运行时内存空间、JVM垃圾回收机制的更多相关文章

  1. JVM运行时数据区和垃圾回收机制

    最近参考各种资料,尤其是<深入理解Java虚拟机 JVM高级特性和最佳实践>,大牛之作.把最近学习的Java虚拟机组成和垃圾回收机制总结一下. 你不会的都是新知识,学无止境,每天进步一点点 ...

  2. Java运行时内存划分与垃圾回收--以及类加载机制基础

    ----JVM运行时内存划分----不同的区域存储的内容不同,职责因为不同1.方法区:被线程共享,存储被JVM加载的类的信息,常量,静态变量等2.运行时常量池:属于方法区的一部分,存放编译时期产生的字 ...

  3. JVM 运行时内存结构

      1.JVM内存模型       JVM运行时内存=共享内存区+线程内存区 1).共享内存区       共享内存区=持久带+堆       持久带=方法区+其他       堆=Old Space ...

  4. JVM运行时内存结构

    原文转载自:http://my.oschina.net/sunchp/blog/369707 1.JVM内存模型 JVM运行时内存=共享内存区+线程内存区 1).共享内存区 共享内存区=持久带+堆 持 ...

  5. JVM运行时内存组成分为一些线程私

    JVM运行时内存组成分为一些线程私有的,其他的是线程共享的. 线程私有 程序计数器:当前线程所执行的字节码的行号指示器. Java虚拟机栈:java方法执行的内存模型,每个方法被执行时都会创建一个栈帧 ...

  6. [转]JVM运行时内存结构

    [转]http://www.cnblogs.com/dolphin0520/p/3783345.html 目录[-] 1.为什么会有年轻代 2.年轻代中的GC 3.一个对象的这一辈子 4.有关年轻代的 ...

  7. JVM02——JVM运行时内存

    在上一篇文章中,我们介绍了 JVM 的内存区域,本文我们将继续围绕 JVM 展开话题,介绍 JVM 运行时内存.关注我的公众号「Java面典」了解更多 Java 相关知识点. Java 堆从 GC 的 ...

  8. 基础篇:JVM运行时内存布局

    目录 1 JVM的内存区域布局 2 JVM五大数据区域介绍 3 JVM运行时内存布局和JMM内存模型区别 4 JMM内存模型交互操作 欢迎指正文中错误 关注公众号,一起交流 参考文章 1 JVM的内存 ...

  9. 详细了解JVM运行时内存

    详细了解JVM运行时内存 1.程序计数器 概念 程序计数器也叫作PC寄存器,是一块很小的内存区域,可以看做是当前线程执行的字节码的行号指示器.字节码的解释工作就是通过改变程序计数器里面的值来获得下一条 ...

随机推荐

  1. iOS 如何通过CocoaPods添加第三方框架

    一  先安装Ruby环境: http://ruby-china.org/wiki/install_ruby_guide 在安装的时候,若是出现: 1.You don't have write perm ...

  2. 怎么启动或停止mysql服务

    在linux下,  启动mysql用 service mysql start   停止用 service mysql stop 在windows下, 启动用 net start mysql    停止 ...

  3. python 处理文件夹中的文件(新建另一个文件保存),listdir顺序输出

    1.原始文件

  4. SVN :This XML file does not appear to have any style information associated with it.

    SVN :This XML file does not appear to have any style information associated with it. The document tr ...

  5. python关于列表转为字典的两个小方法

    1.现在有两个列表,list1 = ['key1','key2','key3']和list2 = ['1','2','3'],把他们转为这样的字典:{'key1':'1','key2':'2','ke ...

  6. 【转】Spring 获取web根目录 (Spring线程获取web目录/路径/根目录,普通类获取web目录)

    不使用Spring,怎样能在Listener启动的Thread中获取web目录,还真不完全确定.其实我觉得实际代码也很简单.就是基于普通的listener,然后在listener中获取web目录并放到 ...

  7. Final-阶段站立会议4

    组名:天天向上 组长:王森 组员:张政.张金生.林莉.胡丽娜 代码地址:HTTPS:https://git.coding.net/jx8zjs/llk.git SSH:git@git.coding.n ...

  8. C++和C代码互相调用是不可避免的

    C++ 编译器能够兼容C语言发编译方式 C++编译器会优先使用C++ 编译的方式 extern 关键字能强制让C++编译器进行C方式的编译 external “C” { //do C-style co ...

  9. 一步一步来做WebQQ机器人-(二)(第一次登陆)

    // 预计会有这些步骤,当然某些步骤可能会合并: 验证码 第一次登陆 第二次登陆 保持在线和接收消息 获取好友和群列表 发送消息 变成智能的(*゚∀゚*) webqq的登陆,分为2步,本文主要讲第一次 ...

  10. EntityFramework code first 一些常用的约束特性

    参阅: https://msdn.microsoft.com/zh-cn/data/jj591583 1. 主键 public class Test { //名称为 ID 的属性会自动映射为主键(自增 ...