文章目录

  • 1:jvm运行时数据区(Run-Time Data Areas)
  • 2:Jvm内存模型
    • 1:jvm内存介绍
    • 2:对象创建过程
    • 3:常见问题
  • 3:Garbage Collect(垃圾回收)-确定一个对象是垃圾
    • 1:引用计数法
    • 2:可达性分析
  • 4:Garbage Collect(垃圾回收)-垃圾回收算法
    • 1:标记清除算法( Mark-Sweep )
    • 2:复制算法(copying)
    • 3:标记整理算法(Mark-Compact)
    • 4: 分代收集算法
      • 1:新生代与复制算法
      • 2:老年代与标记清除或标记整理

1:jvm运行时数据区(Run-Time Data Areas)

1:Method Area(方法区):用于存储已被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等数据
2:Heap(堆):Java对象实例以及数组都在堆上分配。
3:Java Virtual Machine Stacks(虚拟机栈):虚拟机栈是一个线程执行的区域,保存着一个线程中方法的调用状态。换句话说,一个Java线程的运行状态,由一个虚拟机栈来保存,所以虚拟机栈肯定是线程私有的,独有的,随着线程的创建而创
建。
4:The pc Register(程序计数器):如果线程正在执行Java方法,则计数器记录的是正在执行的虚拟机字节码指令的地址;如果正在执行的是Native方法,则这个计数器为空。
5:Native Method Stacks(本地方法栈):如果当前线程执行的方法是Native类型的,这些方法就会在本地方法栈中执行。

2:Jvm内存模型

1:jvm内存介绍

JVM运行时数据区是一种规范,而JVM内存模式是对该规范的实现

一块是非堆区,一块是堆区
堆区分为两大块,一个是Old区,一个是Young区
Young区分为两大块,一个是Survivor区(S0+S1),一块是Eden区
S0和S1一样大,也可以叫From和To

  • 新生代是用来存放新生的对象。一般占据堆的1/3空间。由于频繁创建对象,所以新生代会频繁触发
    MinorGC 进行垃圾回收。新生代又分为 Eden 区、ServivorFrom、ServivorTo 三个区。

    • Eden 区
      Java新对象的出生地(如果新创建的对象占用内存很大,则直接分配到老
      年代)。当Eden区内存不够的时候就会触发MinorGC,对新生代区进行
      一次垃圾回收。
    • ServivorFrom
      上一次 GC 的幸存者,作为这一次 GC 的被扫描者。
    • ServivorTo
      保留了一次 MinorGC 过程中的幸存者。
    • MinorGC 的过程(复制->清空->互换)

MinorGC 采用复制算法。
1 : eden 、 servicorFrom 复制到 ServicorTo,年龄+1
首先,把 Eden和 ServivorFrom区域中存活的对象复制到 ServicorTo区域(如果有对象的年
龄以及达到了老年的标准,则赋值到老年代区),同时把这些对象的年龄+1(如果 ServicorTo 不
够位置了就放到老年区);
2 : 清空 eden 、 servicorFrom
然后,清空 Eden 和 ServicorFrom 中的对象;
3 : ServicorTo 和 ServicorFrom 互换
最后,ServicorTo 和 ServicorFrom 互换,原 ServicorTo 成为下一次 GC 时的 ServicorFrom
区。

  • 老年代
    主要存放应用程序中生命周期长的内存对象。
    老年代的对象比较稳定,所以 MajorGC 不会频繁执行。在进行 MajorGC 前一般都先进行
    了一次 MinorGC,使得有新生代的对象晋身入老年代,导致空间不够用时才触发。当无法找到足
    够大的连续空间分配给新创建的较大对象时也会提前触发一次 MajorGC 进行垃圾回收腾出空间。

MajorGC 采用标记清除算法:首先扫描一次所有老年代,标记出存活的对象,然后回收没
有标记的对象。MajorGC 的耗时比较长,因为要扫描再回收。MajorGC 会产生内存碎片,为了减
少内存损耗,我们一般需要进行合并或者标记出来方便下次直接分配。当老年代也满了装不下的
时候,就会抛出 OOM(Out of Memory)异常。

2:对象创建过程

一般情况下,新创建的对象都会被分配到Eden区,一些特殊的大的对象会直接分配到Old区。

我是一个普通的Java对象,我出生在Eden区,在Eden区我还看到和我长的很像的小兄弟,我们在Eden区中玩了
挺长时间。有一天Eden区中的人实在是太多了,我就被迫去了Survivor区的“From”区,自从去了Survivor
区,我就开始漂了,有时候在Survivor的“From”区,有时候在Survivor的“To”区,居无定所。直到我18岁的
时候,爸爸说我成人了,该去社会上闯闯了。于是我就去了年老代那边,年老代里,人很多,并且年龄都挺大的

3:常见问题

  • 如何理解Minor/Major/Full GC
Minor GC:新生代 GC
Major GC:老年代 GC
Full GC:新生代GC+老年代GC
  • 为什么需要Survivor区?只有Eden不行吗?
如果没有Survivor,Eden区每进行一次Minor GC,存活的对象就会被送到老年代。
这样一来,老年代很快被填满,触发Major GC(因为Major GC一般伴随着Minor GC,也可以看做触发了Full GC)。
老年代的内存空间远大于新生代,进行一次Full GC消耗的时间比Minor GC长得多。
执行时间长有什么坏处?频发的Full GC消耗的时间很长,会影响大型程序的执行和响应速度。可能你会说,那就对老年代的空间进行增加或者较少咯。
假如增加老年代空间,更多存活对象才能填满老年代。虽然降低Full GC频率,但是随着老年代空间加大,一旦发生Full GC,执行所需要的时间更长。
假如减少老年代空间,虽然Full GC所需时间减少,但是老年代很快被存活对象填满,Full GC频率增加。所以Survivor的存在意义,就是减少被送到老年代的对象,进而减少Full GC的发生,Survivor的预筛选保证,只有经历16次Minor GC还能在新生代中存活的对象,才会被送到老年代。
  • 为什么需要两个Survivor区?
最大的好处就是解决了碎片化。也就是说为什么一个Survivor区不行?第一部分中,我们知道了必须设置Survivor区。假设现在只有一个Survivor区,我们来模拟一下流程:
刚刚新建的对象在Eden中,一旦Eden满了,触发一次Minor GC,Eden中的存活对象就会被移动到Survivor区。这样继续循环下去,下一次Eden满了的时候,问题来了,此时进行Minor GC,Eden和Survivor各有一些存活对象,如果此时把Eden区的存活对象硬放到Survivor区,很明显这两部分对象所占有的内存是不连续的,也就导致了内存碎片化。
永远有一个Survivor space是空的,另一个非空的Survivor space无碎片。
  • 新生代中Eden:S1:S2为什么是8:1:1?
新生代中的可用内存:复制算法用来担保的内存为9:1
可用内存中Eden:S1区为8:1
即新生代中Eden:S1:S2 = 8:1:1
现代的商业虚拟机都采用这种收集算法来回收新生代,IBM公司的专门研究表明,新生代中的对象大概98%是“朝生夕死”的
  • 堆内存中都是线程共享的区域吗?
JVM默认为每个线程在Eden上开辟一个buffer区域,用来加速对象的分配,称之为TLAB,全称:Thread Local Allocation Buffer。
对象优先会在TLAB上分配,但是TLAB空间通常会比较小,如果对象比较大,那么还是在共享区域分配。

3:Garbage Collect(垃圾回收)-确定一个对象是垃圾

1:引用计数法

对于某个对象而言,只要应用程序中持有该对象的引用,就说明该对象不是垃圾,如果一个对象没有任
何指针对其
引用,它就是垃圾。
弊端 :如果AB相互持有引用,导致永远不能被回收

2:可达性分析

为了解决引用计数法的循环引用问题,Java 使用了可达性分析的方法。通过一系列的“GC roots”
对象作为起点搜索。如果在“GC roots”和一个对象之间没有可达路径,则称该对象是不可达的。

4:Garbage Collect(垃圾回收)-垃圾回收算法

1:标记清除算法( Mark-Sweep )

最基础的垃圾回收算法,分为两个阶段,标注和清除。标记阶段标记出所有需要回收的对象,清
除阶段回收被标记的对象所占用的空间。如图

从图中我们就可以发现,该算法最大的问题是内存碎片化严重,后续可能发生大对象不能找到可
利用空间的问题。

2:复制算法(copying)

为了解决 Mark-Sweep 算法内存碎片化的缺陷而被提出的算法。按内存容量将内存划分为等大小
的两块。每次只使用其中一块,当这一块内存满后将尚存活的对象复制到另一块上去,把已使用
的内存清掉,如图:

这种算法虽然实现简单,内存效率高,不易产生碎片,但是最大的问题是可用内存被压缩到了原
本的一半。且存活对象增多的话,Copying 算法的效率会大大降低。

3:标记整理算法(Mark-Compact)

结合了以上两个算法,为了避免缺陷而提出。标记阶段和 Mark-Sweep 算法相同,标记后不是清
理对象,而是将存活对象移向内存的一端。然后清除端边界外的对象。如图:

4: 分代收集算法

分代收集法是目前大部分 JVM 所采用的方法,其核心思想是根据对象存活的不同生命周期将内存
划分为不同的域,一般情况下将 GC 堆划分为老生代(Tenured/Old Generation)和新生代(Young
Generation)。老生代的特点是每次垃圾回收时只有少量对象需要被回收,新生代的特点是每次垃
圾回收时都有大量垃圾需要被回收,因此可以根据不同区域选择不同的算法。

1:新生代与复制算法

MinorGC 采用复制算法。

1 : eden 、 servicorFrom 复制到 ServicorTo,年龄+1
首先,把 Eden和 ServivorFrom区域中存活的对象复制到 ServicorTo区域(如果有对象的年
龄以及达到了老年的标准,则赋值到老年代区),同时把这些对象的年龄+1(如果 ServicorTo 不
够位置了就放到老年区);
2 : 清空 eden 、 servicorFrom
然后,清空 Eden 和 ServicorFrom 中的对象;
3 : ServicorTo 和 ServicorFrom 互换
最后,ServicorTo 和 ServicorFrom 互换,原 ServicorTo 成为下一次 GC 时的 ServicorFrom
区。

2:老年代与标记清除或标记整理

而老年代因为每次只回收少量对象,因而采用 Mark-Compact 算法。
MajorGC 采用标记清除算法:

首先扫描一次所有老年代,标记出存活的对象,然后回收没
有标记的对象。MajorGC 的耗时比较长,因为要扫描再回收。MajorGC 会产生内存碎片,为了减
少内存损耗,我们一般需要进行合并或者标记出来方便下次直接分配。当老年代也满了装不下的
时候,就会抛出 OOM(Out of Memory)异常。

JVM-垃圾回收机制相关推荐

  1. 4、JVM垃圾回收机制、新生代的GC、GC(Minor GC、FullGC)、GC日志、JVM参数选项、元空间(笔记)

    4.JVM垃圾回收机制 4.1.新生代的GC 4.1.1.串行GC(SerialGC) 4.1.2.并行回收GC(Parallel Scavenge) 4.1.3.并行GC(ParNew) 4.2.G ...

  2. jvm垃圾回收机制_JVM 垃圾回收机制之堆的分代回收

    JVM垃圾回收机制之堆的分代回收 前言 前文我们了解了Java的GC机制,对于堆中的对象,JVM采用引用计数和可达性分析两种算法来标记对象是否可以清除,本文中我们还会了解到JVM将对分成了不同的区域, ...

  3. jvm对象从新生代到老年代_JVM内存管理、JVM垃圾回收机制、新生代、老年代以及永久代...

    内存模型 JVM运行时数据区由程序计数器.堆.虚拟机栈.本地方法栈.方法区部分组成,结构图如下所示. JVM内存结构由程序计数器.堆.栈.本地方法栈.方法区等部分组成,结构图如下所示: 1)程序计数器 ...

  4. JVM内存区域(Java内存区域)、JVM垃圾回收机制(GC)初探

    一.JVM内存区域(Java内存区域) 首先区分一下JVM内存区域(Java内存区域)和Java内存模型(JMM)的概念.Java线程之间的通信采用的是共享内存模型,这里提到的共享内存模型指的就是Ja ...

  5. JVM架构、JVM垃圾回收机制、垃圾回收算法、垃圾回收器、JMM(内存模型)

    0 JVM和Java的关系 JDK = JRE + Java开发工具(java,javac,javadoc,javap-) JRE = JVM + Java核心类库 即: JDK = JVM + Ja ...

  6. 2.JVM垃圾回收机制-什么时候回收内存

    在前面的文章中,我们介绍过JVM垃圾回收机制负责的是堆和方法区的内存. 参考:http://blog.csdn.net/u011983531/article/details/49227013 在本篇中 ...

  7. JVM垃圾回收机制及算法

    JVM垃圾回收机制 在Java中,程序员是不需要像C++那样显示的去释放一个对象的内存的,而是由虚拟机自行执行.在JVM中,有一个垃圾回收线程,它是低优先级的,在正常情况下是不会执行的,只有在虚拟机空 ...

  8. 【JVM】JVM垃圾回收机制GC

    文章目录 JVM垃圾回收机制 一.堆内存区域划分 1.1内存分配策略 1.2永久代(Permanent Generation) 1.3元空间(MetaSpace) 二.标记算法 2.1引用计数算法 2 ...

  9. 深入理解JVM—垃圾回收机制

    一.前言 明确垃圾收集器关注的部分:堆和方法区.着重学习如何确定哪些垃圾需要回收.垃圾回收算法以及GC触发条件. 二.如何确定哪些垃圾需要回收 1.引用计数算法 在对象中添加一个引用计数器,每当有一个 ...

  10. JVM垃圾回收机制(超级无敌认真好用,万字收藏篇!!!!)

    文章目录 JVM垃圾回收机制 1 判断对象是否存活的算法 1.1 引用计数器算法 1.2 可达性分析算法 2 对象的四种引用方式 2.1 强引用 2.2 软引用 2.3 弱引用 2.4 虚引用 3 垃 ...

最新文章

  1. 基于视觉模型强化学习的通用机器人
  2. C++和C语言中enum 如何使用
  3. 【控制】多智能体系统总结。5.系统合并。
  4. 【虚拟机】关于VMware 提示“无法获得VMCI驱动程序的版本:句柄无效”的解决方案...
  5. URAL 1427. SMS(DP+单调队列)
  6. OA服务器重装操作系统恢复配置
  7. java模拟数据库压测_Jmeter压测工具使用总结
  8. Guide sb. in ding sth. or guide sb. to do sth
  9. 15个开发者最亲睐的Andr​​oid代码编辑器
  10. SwiftUI 教程
  11. Dezender的使用
  12. PIN码-使用与解决办法
  13. ModelState.IsValid 一直是 false的解决办法
  14. 云计算机技术与应用学什么的,云计算技术与应用专业学什么 主要课程
  15. 1021 Deepest Root(dfs,图的联通子集个数,树的深度)
  16. 常用十大免费建站程序介绍
  17. 【JavaWeb】实现网页验证码
  18. 公众号平台域名配置规则
  19. 详解交换机的GVRP
  20. @value值获取不到配置文件值

热门文章

  1. 【转】程序员这口饭-职业规划解决方案
  2. SpringBoot实现Excel、Word转换为PDF
  3. 微软Windows聚焦锁屏壁纸存放目录
  4. 51nod 1534 棋子游戏 博弈
  5. 从“果链”到新能源,立讯精密的B端生意成色几何?
  6. 戴尔计算机更新程序,戴尔电脑怎么关闭自动更新系统
  7. java公司年会抽奖流程图文件流_年会抽奖程序的一些总结
  8. 转 OFBiz财务模型-金融账户
  9. android 车牌字符分割,车牌识别 之 字符分割
  10. java面向接口编程思想