JVM---GC垃圾回收总

目录

1、JVM的内存模型

2、如何判断对象是否可以回收(垃圾判断算法)

3、垃圾回收算法

4、Java中的四种引用

5、造成内存溢出的常见原因

6、JVM堆内存垃圾回收

7、什么是STW?为什么gc要STW(Stop The World)?

8、GC 相关参数


1、JVM的内存模型

        根据虚拟机规范,JVM的内存分为 堆、虚拟机栈、本地方法栈、程序计数器、方法区。

        JDK 1.8 同 JDK 1.7 比,最大的差别就是:元空间取代了永久代。元空间的本质和永久代类似,都是对 JVM 规范中方法区的实现。不过元空间与永久代之间最大的区别在于:元空间并不在虚拟机中,而是使用本地内存。

         虚拟机的内存中主要有程序计数器、虚拟机栈、本地方法栈、堆和方法区。

什么是永久代和元空间?

        方法区是一种规范,不同的虚拟机厂商可以基于规范做出不同的实现,永久代和元空间就是出于不同jdk版本的实现。

        说白了,方法区就像是一个接口,永久代与元空间分别是两个不同的实现类而已。只不过永久代是这个接口最初的实现类,后来这个接口一直进行变更,直到最后彻底废弃这个实现类,由新实现类——元空间进行替代。

        从上图中可以看到,永久代与堆中的老年代是连续的,这里的连续指的是物理地址连续,永久代本身并不在堆中。因此,老年代与永久代其中一个满了,都会触发Full GC。

        由于方法区主要存储类的相关信息,所以对于动态生成类的情况比较容易出现永久代的内存溢出。最典型的场景就是,在 jsp 页面比较多的情况,容易出现永久代内存溢出,会报出"java.lang.OutOfMemoryError: PermGen space "异常。

        元空间(Metaspace),不再与堆连续,而是直接存在于本地内存中,也就是机器的内存。理论上机器内存有多大,元空间的野心就有多大。

Java8中,使用元空间替换永久代的原因:
        在之前的版本中,字符串常量池存在于永久代中,在大量使用字符串的情况下,非常容易出现OOM的异常。此外,JVM加载的class的总数,方法的大小等都很难确定,因此对永久代大小的指定难以确定。太小的永久代容易导致永久代内存溢出,太大的永久代则容易导致虚拟机内存紧张。

2、如何判断对象是否可以回收(垃圾判断算法)

        引用计数法:一个对象被其它变量所引用,计数+1。如果某一个变量不再引用它了,计数-1。                             当计数为0时可以被回收。

        存在问题:如果发生循环引用,如下图。A、B两个对象都不会被回收,计数都为1。

        可达性分析算法 :首先会确定一系列的根对象(GC Root),按照从上至下的方式搜索被根对象集                                  合所连接的目标对象是否可达,如果该对象被跟对象直接或间接的引用,就                                    不能被回收,否则就会被回收。该算法可以有效地解决在引用计数算法中循                                     环引用的问题,防止内存泄漏的发生。

        哪些对象可以作为GC Root:

                               虚拟机栈中引用的对象:各个线程被调用的方法中使用到的参数、局部变量等。

                                本地方法栈内 JNI(通常说的本地方法)引用的对象

                                方法区中类静态属性引用的对象 比如:Java类的引用类型静态变量

                                方法区中常量引用的对象 比如:字符串常量池(string Table)里的引用

                                所有被同步锁 synchronized 持有的对象

                                Java虚拟机内部的引用。

 3、垃圾回收算法

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

         优点:速度快

        缺点:内存碎片化严重,后续可能发生大对象不能找到可利用空间的问题,会造成内存溢出。

        2、标记-整理算法(Mark-Compact)

            标记后不是清理对象,而是将存活对象移向内存的一端。然后清除端边界外的对象。

        优点:没有内存碎片

        缺点:速度慢、内存开销大 

       3、复制算法(Copying)

             按内存容量将内存划分为等大小的两块。每次只使用其中一块,当这一块内存满后将尚存活的对象复制到另一块上去,把已使用的内存清掉。

         优点:速度快、不会有内存碎片

         缺点:占用双倍空间

4、Java中的四种引用

        强引用:强引用j就是我们常见的普通引用对象,我们程序中几乎所有的引用使用的都是强引                         用。只要还有一个强引用指向一个对象,就表明该对象还活着,不能被回收

        软引用:一个软引用中的对象,不会很快被JVM回收,当JVM内存不足时,才会对其进行回收

        弱引用:比软引用拥有更短的生命周期。在垃圾回收时,只要发现弱引用,不管堆空间是否                         足够,都会将对象进行回收。由于垃圾回收器是一个优先级很低的线程,因此不一定                      很快发现那些只具有弱引用的对象。

        虚引用:虚引用 就是形同虚设它并不能决定 对象的生命周期。任何时候这个只有虚引用的对                        象都有可能被回收。因此,虚引用主要用来跟踪对象的回收,清理被销毁对象的相关                      资源。

5、造成内存溢出的常见原因

        StackOverFlowError
        解释:线程栈内存溢出,
        原因:方法递归调用

        OutOfMemoryError:Java heap memory
        解释:堆内存溢出
        原因:大量对象创建撑爆堆区

        OutOfMemoryError:Metaspace
        解释:方法区溢出
        原因:大量类被加载

6、JVM堆内存垃圾回收

Java 的自动内存管理主要是针对对象内存的回收对象内存的分配。同时,Java 自动内存管理最核心的功能是 堆 内存中对象的分配与回收。

        堆中存放我们new出来的对象,存放的区域就是Eden区域,但这个区域存满以后就会做minor gc,首先通过可达性分析算法来判断是否是垃圾,如果能够找到引用就不是垃圾,找不到就是垃圾,minor gc过程中我们有一部分是垃圾一部分不是垃圾,会将这些垃圾对象清除,然后非垃圾对象会放到survivor区域的to中并且将对象的分代年龄+1,分代年龄(用来区分对象生命周期的一种标识,比如parallel默认对象分代年龄达到15岁就放到老年代中)。此时一次minor gc结束。我们可以推断出,老年代做full gc的频率应该远远小于年轻代minor gc,老年代等到存放对象快满的时候会做full gc,扫描老年代中的对象是否是垃圾,如果都不是并且此时还有对象要进入老年代,那此时就会报OOM(内存溢出错误)。

        新生代使用的复制算法,老年代使用的是标记整理算法。

7、什么是STW?为什么gc要STW(Stop The World)?

        指的是GC事件发生过程中,会产生应用程序的停顿。停顿产生时整个应用程序线程都会被暂停,没有任何响应, 有点像卡死的感觉,这个停顿称为STW。可达性分析算法中枚举根节点(GC Roots)会导致所有Java执行线程停顿。

        原因很简单,因为java进行垃圾回收时使用可达性分析,从GC Root向下判断对象是否有引用,如果不把所有线程进入safe points并阻塞起来就会出现对象上一秒没有引用被删除,后一秒又出现引用,导致错误的产生。

8、GC 相关参数

        

        

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Rk..

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值