• 三、JVM垃圾回收1(如何寻找垃圾?)


      根据《深入理解java虚拟机》这本书总结

      书中有一段话,大体的意思是:java和c之间有一堵墙,墙里的人想出来,墙外的人想进去,这堵墙就是垃圾回收机制了。

    一、为什么要理解垃圾回收机制?

      java的垃圾回收,是自动完成的,一般情况下并不需要去关注,但是当遇到一些并发量、数据量比较大的时候,可能就会出现一些关于内存益处的问题。这时候,解决的办法,就得依靠对垃圾回收机制来理解和进行调优了。我们可以分析,是哪部分内存出现了问题,分析哪些多余的对象应为代码问题没有被回收。我想这就是学java的人想进去这堵墙的原因吧。

    二、垃圾回收的主要作用对象?

      jvm内存,主要分五个部分:堆、方法区、栈、本地方法栈、程序计数器。这五个区域中,除了程序计数器,别的四个区域都是可能会存在内存溢出问题的。但是,对于本地方法栈和栈来说,jvm会在方法入栈时候开辟内存,出栈则回收内存,没有什么很复杂的算法和操作。所以,垃圾回收机制,主要正对的是堆和方法区这两部分内存区域中对象的回收。

    三、如何寻找垃圾(无用对象)?

      在堆和方法区回收垃圾对象,需要先找到无用对象,一般有两种方法:

      1、引用计数法

        为每个对象添加一个记录被引用次数的属性,当对象引用或者引用失效时,进行更新+1或者-1的操作,并且随时更新,当gc发生的时候,如果引用计数为0,则判断对象可以进行回收。

        但是这种方法有个弊端,如果两个对象存在着相互引用的情况,两个对象本质上都无地方使用了,但是因为两个无用对象相互引用,那么计数器永远不肯呢个为0,就永远不能清楚这两个对象了。所以一般jvm虚拟机,不会直接使用这种方法。  

      2、可达性算法

      (1)虚拟机会设置一些root节点,一般可以作为root节点的有:栈帧中本地变量表引用对象、本地方法引用对象、方法区中常量引用对象、方法区中静态变量引用的对象。

      (2)根据这些root节点,向下搜索,所有走过的路径所涉及的对象,即是有用对象,其余的都为无用对象。这样,即使一些相互引用的对象,但是与root节点无关联,也会被标记回收。

    四、垃圾的自救

      jvm给了即将被回收的垃圾一个自救的机会,所以在对对象进行垃圾gc标记的时候,会有两个过程:

        1、第一次标记,会查看该对象是否重新了finalize()方法,如果重写了该方法,那就标记需要执行这个方法,如果没有重新,则标记为垃圾,在下次gc进行回收。

        2、如果需要执行finalize方法,会在回收之前执行,如果在该方法中进行本对象重新引用,则成功自救,将不进行垃圾回收。如果没有重新引用,则仍然会在下次gc的时候进行回收。

      *一个对象的finalize方法,有且只能执行一次,所以顶多能自救一次 

       

  • 相关阅读:
    hdu-5492 Find a path(dp)
    hdu-5493 Queue(二分+树状数组)
    bzoj-2243 2243: [SDOI2011]染色(树链剖分)
    codeforces 724
    codeforces 422A A. Borya and Hanabi(暴力)
    codeforces 442C C. Artem and Array(贪心)
    codeforces 442B B. Andrey and Problem(贪心)
    hdu-5918 Sequence I(kmp)
    poj-3739. Special Squares(二维前缀和)
    hdu-5927 Auxiliary Set(树形dp)
  • 原文地址:https://www.cnblogs.com/guoliangxie/p/7263611.html
Copyright © 2020-2023  润新知