美文网首页
java-jvm垃圾回收

java-jvm垃圾回收

作者: 渐入晚冬 | 来源:发表于2018-08-14 10:44 被阅读0次

java为什么要做垃圾回收

        在C++中,对象所占的内存在程序结束运行之前一直被占用,在明确释放之前不能分配给其它对象;而在Java中,当没有对象引用指向原先分配给某个对象的内存时,该内存便成为垃圾。垃圾回收能自动释放内存空间,减轻编程的负担,JVM的一个系统级线程会自动释放该内存块。垃圾回收意味着程序不再需要的对象是"无用信息",这些信息将被丢弃。当一个对象不再被引用的时候,内存回收它占领的空间,以便空间被后来的新对象使用。事实上,除了释放没用的对象,垃圾回收也可以清除内存记录碎片。由于创建对象和垃圾回收器释放丢弃对象所占的内存空间,内存会出现碎片。碎片是分配给对象的内存块之间的空闲内存洞。碎片整理将所占用的堆内存移到堆的一端,JVM将整理出的内存分配给新的对象。

jvm内存模型

堆栈分开设计是为什么呢?

       栈存储了处理逻辑、堆存储了具体的数据,这样隔离设计更为清晰

       堆与栈分离,使得堆可以被多个栈(线程)共享。另一方面,堆中的共享常量和缓存可以被所有栈访问,节省了空间。

       栈保存了上下文的信息,因此只能向上增长;而堆是动态分配

1.栈区JVM Stack

线程私有,生命周期与线程相同。每个方法执行的时候都会创建一个栈帧(stack frame)用于存放基本数据类型和堆中对象的引用、局部变量表、操作栈、动态链接、方法出口。栈中一个对象只对应了一个4btye的引用。

2.本地方法栈Native Stack

本地方法栈区,与jvm stack类似,不过此区域是为调用本地方法服务的(栈的空间大小远远小于堆)

3.堆(Heap)

存放对象实例、数组等,所有的对象的内存都在这里分配。垃圾回收主要就是作用于这里的。

4.方法区

方法区与Java堆一样,是各个线程共享的区域,它用于存储已被虚拟机加载的类信息,常量,静态变量,即时编译(JIT)后的代码等数据。

虽然Java虚拟机规范把方法区描述为堆的一个逻辑部分,但是它却有一个别名叫做Non-Heap(非堆),目的应该是与Java堆区分开来。

5.程序计数器

这里记录了线程执行的字节码的行号,在分支、循环、跳转、异常、线程恢复等都依赖这个计数器。

堆内存分配机制

Young Generation年轻代

Eden伊甸园区

Survivor Space两个存活区

Old Generation老年代

jvm垃圾回收机制

    要了解回收机制前需要了解一下概念

     分配原则:

        对象优先在Eden区域分配

        大对象直接进入老年代

        长期存活的对应将进入老年代

        class、常量等信息jvm直接加载进方法区

     GC定义:

        活对象:被引用的对象

        垃圾对应:不再被引用的对象

        垃圾回收是发现活对象和回收垃圾对象的过程

      GC的作用:

        分配内存

        确保被引用对象不被回收

        回收不可达对象

      java引用类型:

        强引用-Object o = new Object();如果不释放引用是不会被回收的

        软引用-在内存不足要发生一出时进行回收,适合cache使用

        弱引用-比软引用更弱,无论内run是否足够都会被回收

        虚引用-无法通过引用获取对象实力,也不会影响对象生命周期,只是希望垃圾回收时收到一个系统通知

jvm内存申请过程

1.绝大多数刚创建的对象会被分配在Eden区,其中的大多数对象很快就会消亡,Eden区是连续的内存空间,因此在其上分配内存极快

2.当Eden区满的时候,执行MinorGC,将消亡的对象清理,并将剩余的对象复制到一个存货去Survivor0

3.此后,每次Eden满了,就执行一次MinorGC,将消亡的对象清理,并将剩余的对象都添加到Survivor0

4.当Survivor0也满的时候,将其中仍然存活的对象直接复制到Survivor1,以后Eden执行MinorGC后,就将剩余的对象添加到SUrvivor1

5.当两个存活区切换了几次(HotSpot虚拟机默认15次,用-XX:MaxTenuringThreshold控制,大于该值进入老年代,但这只是个最大值,并不代表一定是这个值)之后,仍然存活的对象将复制到老年代

6.大对象直接进入老年代

7.当Old区的空间不够时,JVM会在Old区进行FULLGC

8.垃圾完全回收后,若Survivor及Old区仍然无法存放从Eden区复制过来的部分对象,会导致JVM无法在Eden区为新对象创建内存区域,则会导致Out of memory错误

2.几种垃圾回收机制

2.1.标记-清除收集器

这种收集器首先遍历对象图并标记可到达的对象,然后扫描堆栈以寻找未标记对象并释放它们的内存。这种收集器一般使用单线程工作并停止其他操作。

2.2.标记-压缩收集器

有时也叫标记-清除-压缩收集器,与标记-清除收集器有相同的标记阶段。在第二阶段,则把标记对象复制到堆栈的新域中以便压缩堆栈。这种收集器也停止其他操作。

2.3.复制收集器

这种收集器将堆栈分为两个域,常称为半空间。每次仅使用一半的空间,jvm生成的新对象则放在另一半空间中。gc运行时,它把可到达对象复制到另一半空间,从而压缩了堆栈。这种方法适用于短生存期的对象,持续复制长生存期的对象则导致效率降低。

2.4.增量收集器

增量收集器把堆栈分为多个域,每次仅从一个域收集垃圾。这会造成较小的应用程序中断。

2.5.分代收集器

这种收集器把堆栈分为两个或多个域,用以存放不同寿命的对象。jvm生成的新对象一般放在其中的某个域中。过一段时间,继续存在的对象将获得使用期并转入更长寿命的域中。分代收集器对不同的域使用不同的算法以优化性能。

2.6.并发收集器

并发收集器与应用程序同时运行。这些收集器在某点上(比如压缩时)一般都不得不停止其他操作以完成特定的任务,但是因为其他应用程序可进行其他的后台操作,所以中断其他处理的实际时间大大降低。

2.7.并行收集器

并行收集器使用某种传统的算法并使用多线程并行的执行它们的工作。在多cpu机器上使用多线程技术可以显著的提高java应用程序的可扩展性。

相关文章

  • java-jvm垃圾回收

    java为什么要做垃圾回收 在C++中,对象所占的内存在程序结束运行之前一直被占用,在明确释放之前不能分配给其它...

  • 简单理解垃圾回收

    什么是垃圾回收? 垃圾回收的是什么? 如何判断为垃圾? 垃圾是怎样被回收的? 垃圾回收哪些区域的内存? 什么是垃圾...

  • JVM(二) GC算法与分代回收策略

    可达性分析 GCRoot场景 垃圾回收算法 分代回收策略 引用 垃圾回收 垃圾回收(Garbage Collect...

  • JVM调优之垃圾定位、垃圾回收算法、垃圾处理器对比

    谈垃圾回收器之前,要先讲讲垃圾回收算法,以及JVM对垃圾的认定策略,JVM垃圾回收器是垃圾回收算法的具体实现,了解...

  • 01垃圾回收机制

    垃圾回收(Garbage Collection,GC) 垃圾回收就是释放垃圾占用的空间 内存的动态分配和垃圾回收,...

  • Java 垃圾收集(GC)浅谈

    Java 垃圾收集(GC)浅谈 为什么需要垃圾回收?哪些内存需要回收?什么时候回收?如何回收? 为什么需要垃圾回收...

  • JVM垃圾回收机制

    JVM垃圾回收 整体思维导图 带着问题理解JVM垃圾回收机制 Java为什么需要垃圾回收机制; 回收哪部分垃圾; ...

  • 垃圾回收

    如何查看当前JVM使用的垃圾回收器? 如何指定使用CMS回收? 如何打印回收日志? 垃圾回收过程 CMS垃圾回收的...

  • JVM常见垃圾回收器介绍

    垃圾回收器简介 在新生代和老年代进行垃圾回收的时候,都是要用垃圾回收器进行回收的,不同的区域用不同的垃圾回收器。分...

  • JavaScript的垃圾回收机制

    大纲 1、认识垃圾回收机制2、垃圾回收机制的原理3、垃圾回收机制的标记策略4、垃圾回收机制与内存管理 1、认识垃圾...

网友评论

      本文标题:java-jvm垃圾回收

      本文链接:https://www.haomeiwen.com/subject/vvjybftx.html