博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
三、JVM垃圾回收1(如何寻找垃圾?)
阅读量:6539 次
发布时间:2019-06-24

本文共 1215 字,大约阅读时间需要 4 分钟。

  根据《深入理解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方法,有且只能执行一次,所以顶多能自救一次 

   

转载于:https://www.cnblogs.com/guoliangxie/p/7263611.html

你可能感兴趣的文章
逆向输出回环数组
查看>>
自己动手,实现“你的名字”滤镜
查看>>
高清摄像头MIPI CSI2接口浅解【转】
查看>>
C# CancellationTokenSource和CancellationToken的实现
查看>>
PCIE BAR空间
查看>>
winform命名规范
查看>>
如何用数学课件制作工具画角平分线
查看>>
VS2015 中统计整个项目的代码行数
查看>>
Anaconda入门使用指南
查看>>
UWP控件与DataBind
查看>>
bash: php: command not found
查看>>
XVIII Open Cup named after E.V. Pankratiev. Eastern Grand Prix
查看>>
数据恢复软件如何换机使用?
查看>>
《高性能mysql》到手
查看>>
(转)关于如何学好游戏3D引擎编程的一些经验
查看>>
使用Kotlin为你的APP自定义一个统一的标题栏
查看>>
EF各版本增删查改及执行Sql语句
查看>>
拓扑排序
查看>>
jQGrid API
查看>>
Bzoj1758: [Wc2010]重建计划
查看>>