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

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

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

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

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

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

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

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

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

  1、引用计数法

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

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

  2、可达性算法

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

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

  

   

时间: 2024-10-29 19:12:25

JVM垃圾回收1(如何寻找垃圾?)的相关文章

java垃圾回收 - 为什么要进行垃圾回收

1.为什么要进行垃圾回收:      在C++中,对象所占的内存在程序结束运行之前一直被占用,在明确释放之前不能分配给其它对象:而在Java中,当没有对象引用指向原先分配给某个对象 的内存时,该内存便成为垃圾. 垃圾回收能自动释放内存空间,减轻编程的负担,JVM的一个系统级线程会自动释放该内存块.垃圾回收意味着程序不再需要的对象是"无用信息",这些信息将被丢弃.当一个对 象不再被引用的时候,内存回收它占领的空间,以便空间被后来的新对象使用.事实上,除了释放没用的对象,垃圾回收也可以清除

JavaScript垃圾回收(二)——垃圾回收算法

一.引用计数(Reference Counting)算法 Internet Explorer 8以下的DOM和BOM使用COM组件所以是引用计数来为DOM对象处理内存,引用计数的含义是跟踪记录每个值被引用的次数.形象点说: 1)房子里有很多便签纸,这些纸就好比是内存.如下图: 2)使用内存,就好比在这些纸上写字.但是,有个条件,任何使用一张纸的人,必须在纸的一角写上计数1,如果2个人同时使用一张纸,那么计数就变成2,以此类推.当一个人使用完某张纸的时候,必须把角上的计数减1,这样,一旦当计数变为

JVM内存模型及垃圾回收机制

JVM内存模型1.栈Java栈是与每一个线程关联的,JVM在创建每一个线程的时候,会分配一定的栈空间给线程.存储局部变量.引用.方法.返回值等.StackOverflowError:如果在线程执行的过程中,栈空间不够用,那么JVM就会抛出此异常,这种情况一般是死递归造成的.2.堆 Java中堆是由所有的线程共享的一块内存区域,堆用来保存各种JAVA对象,比如数组,线程对象等. 2.1堆的分代JVM堆一般分为三个部分:Young:年轻代Young区被划分为三部分,Eden区和两个大小严格相同的Su

JVM垃圾回收机制总结(3) :按代垃圾收集器

为什么要分代 分代的垃圾回收策略,是基于这样一个事实:不同的对象的生命周期是不一样的 . 因此,不同生命周期的对象可以采取不同的收集方式,以便提高回收效率. 在Java程序运行的过程中,会产生大量的对象,其中有些对象是与业务信息相关,比如Http请求中的Session对象.线程.Socket连接,这 类对象跟业务直接挂钩,因此生命周期比较长.但是还有一些对象,主要是程序运行过程中生成的临时变量,这些对象生命周期会比较短,比如:String对 象,由于其不变类的特性,系统会产生大量的这些对象,有些

JVM内存管理和垃圾回收机制介绍

http://backend.blog.163.com/blog/static/20229412620128233285220/ 内存管理和垃圾回收机制是JVM最核心的两个组成部分,对其内部实现的掌握是Java开发人员开发出高质量的Java系统的必备条件.最近整理了一些关于JVM内存管理和垃圾回收方面的知识,这里梳理一下,分享给大家,希望能够对Java虚拟机有更深入的了解. 1. JVM内存管理 首先,JVM将内存组织为主内存和工作内存两个部分.主内存中主要包括本地方法区和堆.每个线程都有一个工

JVM垃圾回收算法 总结及汇总

先看一眼JVM虚拟机运行时的内存模型: 1.方法区 Perm(永久代.非堆) 2.虚拟机栈 3.本地方法栈 (Native方法) 4.堆 5.程序计数器 1 首先的问题是:jvm如何知道那些对象需要回收 ? 目前两种标识算法.三种回收算法.两种清除算法.三种收集器 引用计数法 每个对象上都有一个引用计数,对象每被引用一次,引用计数器就+1,对象引用被释放,引用计数器-1,直到对象的引用计数为0,对象就标识可以回收 这个可以用数据算法中的图形表示,对象A-对象B-对象C 都有引用,所以不会被回收,

JVM垃圾回收算法(最全)

JVM垃圾回收算法(最全) 下面是JVM虚拟机运行时的内存模型: 1.方法区 Perm(永久代.非堆) 2.虚拟机栈 3.本地方法栈 (Native方法) 4.堆 5.程序计数器 1 首先的问题是:jvm如何知道那些对象需要回收 ? 目前两种标识算法.三种回收算法.两种清除算法.三种收集器 引用计数法 每个对象上都有一个引用计数,对象每被引用一次,引用计数器就+1,对象引用被释放,引用计数器-1,直到对象的引用计数为0,对象就标识可以回收 这个可以用数据算法中的图形表示,对象A-对象B-对象C

第三章 JVM内存回收区域+对象存活的判断+引用类型+垃圾回收线程

注意:本文主要参考自<深入理解Java虚拟机(第二版)> 说明:查看本文之前,推荐先知道JVM内存结构,见<第一章 JVM内存结构> 1.内存回收的区域 堆:这是GC的主要区域 方法区:回收两样东西 无用的类 废弃的常量 栈和PC寄存器是线程私有区域,不发生GC 2.怎样判断对象是否存活 垃圾回收:回收掉死亡对象所占的内存.判断对象是否死亡,有两种方式: 引用计数法 原理:给对象添加一个引用计数器,每当有一个地方引用它时,计数器值+1:引用失效时,计数器值-1 实际中不用,不用的两

JVM调优系列:(四)GC垃圾回收

跟踪收集算法: 复制(copying): 将堆内分成两个相同空间,从根(ThreadLocal的对象,静态对象)开始访问每一个关联的活跃对象,将空间A的活跃对象全部复制到空间B,然后一次性回收整个空间A.因为只访问活跃对象,将所有活动对象复制走之后就清空整个空间,不用去访问死对象,不需要标记骤,所以遍历空间的成本较小,但需要巨大的复制成本和较多的内存. 标记清除(mark-sweep): 收集器先从根开始访问所有对象,标记活跃对象.然后再遍历一次整个内存区域,把所有没有标记活跃的对象进行回收处理

Jvm垃圾回收——第二章

上文简单介绍了JVM的一些原理作为铺垫,接下来介绍一下垃圾回收. java的垃圾回收机制,主要采用的是分代回收机制. 分为: 1)新生代:新出生的对象在这里创建,又分为一个eden(伊甸园,这个名字很贴切),两个survivor区. 刚刚出生的小baby,当然放在eden, 2)旧生代:因为在新生代活的较长,在若干次内存回收后进入这,作为生命周期较长的对象. 3)持久代:主要是类二进制字节码,放在方法区. 以上三个地方就是内存回收进行的主要场地. 为什么采用这种方式呢? 我有一些自己的看法,对整