前言

在前面的文章中,介绍了JVM内存模型分为:堆区、虚拟机栈、方法区、本地方法区和程序计数器,其中堆区是JVM中最大的一块内存区域,在Java中的所有对象实例都保存在此区域,它能被所有线程共享。

在Java中还有一个重要的机制:GC(垃圾收集器),堆是GC管理的主要区域,本文会带大家了解GC机制。

GC的简介

GC(Garbage Collection)垃圾收集机制是Java一个重要特性。不同于C/C++语言需要程序员自己管理内存的回收,而且这样做往往容易出错,导致内存泄漏等严重问题。

Java程序员不用编写回收内存的代码,因为Java有GC机制,它是一个特殊的后台线程,该线程对JVM中的内存进行标记,并确定哪些需要回收,再通过一定的回收策略自动回收内存,它在后台一直运行,保证JVM不会出现内存溢出的问题。

对象回收的算法

那么GC是如何判断某个对象的内存需要回收呢?GC需要判断该对象已死,也就是不再被调用,如何判断对象不再被调用呢?

这里有两种算法:

引用计数算法

可达性分析算法

引用计数算法

该算法给每个对象分配一个计数器,当有引用指向这个对象时,计数器加1,当指向该对象的引用失效时,计数器减一。最后如果该对象的计数器为0时,java垃圾回收器会认为该对象是可回收的。

优点:

1、实时性高,只要对象计数器为0就进行回收,不用等到内存不足的时候。

2、在垃圾回收过程中,应用无需挂起。

3、更新对象的计数器时,只是影响到该对象,不会扫描全部对象。

缺点:

每次引用对象时,都会更新计数器,有时间消耗

不能解决循环引用问题

那什么是循环引用问题呢?我们看下面这段代码:

class ClassA{

ClassB b;

}

class ClassB{

ClassA a;

}

public static void main(String[] args){

ClassA a = new ClassA();

ClassB b = new ClassB();

a.b = b;

b.a = a;

a = null;

b = null;

}

上面的a、b两个对象虽然都赋值为null,但是都不能回收,因为存在循环引用,它们的计数器不为0.

可达性分析算法

该算法通过一种被称作“GC Root”的对象作为起始点,从这些节点开始向下搜索,搜索所走过的路径称为引用链,当一个对象到GC Roots没有任何引用链相连时,则证明此对象时不可用的。

如下图:

在Java语言中,可作为GC Roots对象包括下面几种:

1)虚拟机栈中引用的对象

2)方法区中类静态属性引用的对象

3)方法区常量池中引用的对象

3)本地方法栈中JNI引用的对象

再回头看前面这段代码,虽然a和b对象的引用计数都不为0,但是它们作为GC Root对象,最后都赋值为null,导致引用不可达,这样两个对象都是可以被回收的。

总结

本文我们学习了JVM中的垃圾收集(GC)机制,GC是一个在后台持续运行的线程,帮助我们回收JVM堆中的对象内存,保证JVM不会内存溢出。

如何判断对象内存需要回收,有两个算法:引用计数算法和可达性分析算法。

引用计数算法通过判断对象的引用计数为0,就标记该对象内存可以回收,但是不能很好的解决循环引用问题;可达性分析算法通过GC Root向下搜索,如果引用链相连则对象可达,否则标记对象不可达,可以进行回收,这种算法能很好解决对象循环引用问题。

JVM垃圾回收机制之对象回收算法的更多相关文章

  1. JVM垃圾回收机制与内存回收

    暂时转于:https://blog.csdn.net/qq_27035123/article/details/72857739 垃圾回收机制 GC是垃圾回收机制,java中将内存管理交给垃圾回收机制, ...

  2. Java的垃圾回收机制:强制回收System.gc() Runtime.getTime().gc()

    垃圾回收 当引用类型的实体,如对象.数组等不再被任何变量引用的时候.这块占用的内存就成为了垃圾.JVM会根据自己的策略决定是回收内存 注意: 垃圾回收只回收内存中的对象,无法回收物理资源(数据库连接, ...

  3. 2.1.JVM的垃圾回收机制,判断对象是否死亡

    因为热爱,所以坚持. 文章下方有本文参考电子书和视频的下载地址哦~ 这节我们主要讲垃圾收集的一些基本概念,先了解垃圾收集是什么.然后触发条件是什么.最后虚拟机如何判断对象是否死亡. 一.前言   我们 ...

  4. JVM中垃圾回收机制如何判断是否死亡?详解引用计数法和可达性分析 !

    因为热爱,所以坚持. 文章下方有本文参考电子书和视频的下载地址哦~ 这节我们主要讲垃圾收集的一些基本概念,先了解垃圾收集是什么.然后触发条件是什么.最后虚拟机如何判断对象是否死亡. 一.前言   我们 ...

  5. 理解Android Java垃圾回收机制

    Jvm(Java虚拟机)内存模型 从Jvm内存模型中入手对于理解GC会有很大的帮助,不过这里只需要了解一个大概,说多了反而混淆视线. Jvm(Java虚拟机)主要管理两种类型内存:堆和非堆.堆是运行时 ...

  6. 浅谈Chrome V8引擎中的垃圾回收机制

    垃圾回收器 JavaScript的垃圾回收器 JavaScript使用垃圾回收机制来自动管理内存.垃圾回收是一把双刃剑,其好处是可以大幅简化程序的内存管理代码,降低程序员的负担,减少因 长时间运转而带 ...

  7. 浅谈V8引擎中的垃圾回收机制

    最近在看<深入浅出nodejs>关于V8垃圾回收机制的章节,转自:http://blog.segmentfault.com/skyinlayer/1190000000440270 这篇文章 ...

  8. Java垃圾回收机制概述

    总览 本文会介绍垃圾回收的以下几个方面. 为什么要垃圾回收 在哪里回收 哪些对象需要回收 怎么回收 HotSpotJVM中有哪些具体的回收器可以直接用. 在开始讲垃圾回收之前,先通过一张图快速回忆一下 ...

  9. .Net 垃圾回收机制原理(二)

    英文原文:Jeffrey Richter 编译:赵玉开 链接http://www.cnblogs.com/yukaizhao/archive/2011/11/25/dot_net_GC_2.html ...

随机推荐

  1. Dubbo源码构建

    代码签出 通过以下的这个命令签出最新的项目源码: git clone https://github.com/apache/incubator-dubbo.git dubbo 分支 我们使用 maste ...

  2. python 在内网windows环境下pip三方包

    我没用过Linux环境. 一般情况下,内网安装三方包,只需要在pypi找到对应python版本(2.7,3.6,...),系统位数(32位,64位)的whl包,cmd命令行cd进入相关目录,pip i ...

  3. java基础3(二)

    基础加强 类加载器 A.类加载器获取classpath下任意内容 注意: 可以通过ClassLoader可以获取classpath下的所有内容. SpringMVC 1.整体架构 流程图 2.流程细节 ...

  4. equals方法中变量在前和在后的区别

    对于变量:String str1; 使用str1.equals("null"); 对于变量str1,如果str1是null,空是没有equals方法的,会抛出空指针异常 使用&qu ...

  5. ESP32搭建4.esp32官方程序下载与串口读取

    上一篇写到esp-idf的整体环境搭建,本文主要讲讲如何将examples中的例子烧写到ESP32的flash中,以及如何通过linux串口进行调试. 一. Esp32程序下载 1.Ctrl+Alt+ ...

  6. elasticsearch(1) 安装和使用

    一.简介 Elasticsearch是一个基于Apache Lucene(TM)的开源搜索引擎.无论在开源还是专有领域,Lucene可以被认为是迄今为止最先进.性能最好的.功能最全的搜索引擎库. 但是 ...

  7. 给定一个只包含正整数的非空数组,返回该数组中重复次数最多的前N个数字 ,返回的结果按重复次数从多到少降序排列(N不存在取值非法的情况)

    """ #给定一个只包含正整数的非空数组,返回该数组中重复次数最多的前N个数字 #返回的结果按重复次数从多到少降序排列(N不存在取值非法的情况) 解题思路: 1.设定一个 ...

  8. 马凯军201771010116《面向对象与程序设计Java》第十三周学习总结

    实验十三  图形界面事件处理技术 实验时间 2018-11-22 理论知识与学习部分 事件处理基础  事件源(event source):能够产生事件的对象都可 以成为事件源,如文本框.按钮等.一个事 ...

  9. bootstrap-edittable 使用笔记之 (select, data,text, number)

    可编辑列表的数据格式可以指定,常用的有select, data, text, number.代码如下. 前端代码: <table id="tb_product" class= ...

  10. tp5 删除服务器文件

    public function test(){ //ROOT_PATH . 'public' . DS . 'uploads' $filename = ROOT_PATH . 'public' . D ...