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

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

GC的简介

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

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

对象回收的算法

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

这里有两种算法:

1、引用计数算法

2、可达性分析算法

引用计数算法

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

优点:

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

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

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

缺点:

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

2、不能解决循环引用问题

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

1. class ClassA{

2.   ClassB b;

3. }

4. class ClassB{

5.   ClassA a;

6. }

7. public static void main(String[] args){

8.   ClassA a = new ClassA();

9.   ClassB b = new ClassB();

10.   a.b = b;

11.   b.a = a;

12.   a = null;

13.   b = null;

14. }

上面的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向下搜索,如果引用链相连则对象可达,否则标记对象不可达,可以进行回收,这种算法能很好解决对象循环引用问题。

转载于:https://blog.51cto.com/14249543/2407491

好程序员Java教程分享之jvm篇相关推荐

  1. hibernate savealiasentity 保存后id为空_好程序员Java教程分享Java面试题之Hibernate

    好程序员Java教程分享Java面试题之Hibernate 1.简书一下Hibernated的开发流程 第一步:加载Hibernate的配置文件,读取配置文件的参数, 第二步:创建SessionFac ...

  2. 好程序员Java教程分享JavaScript面试问题及答案(一)

    好程序员Java教程分享JavaScript面试问题及答案(一) 1.使用 typeof bar === "object" 来确定 bar 是否是对象的潜在陷阱是什么?如何避免这个 ...

  3. java static关键字_好程序员Java教程分享static关键字的理解

    好程序员Java教程分享static关键字的理解,static关键字含义可以理解为静态的. 1. 当其修饰属性时,该属性为整个类公有,所有的对象操作的都是同一个静态属性.所以调用时应该使用类名去调用, ...

  4. java post请求 json_好程序员Java教程分享Vue插件之Axios

    好程序员Java教程分享Vue插件之Axios 环境安装: npm install --save axios vue-axios //安装axios Npm install //安装依赖 在main. ...

  5. java喷泉编码_好程序员Java教程分享使用JS实现简单喷泉效果

    原标题:好程序员Java教程分享使用JS实现简单喷泉效果 好程序员Java教程分享使用JS实现简单喷泉效果,最近,在教学生使用JS的基本操作,为了练习JS的基本作用,特地写了一个喷泉效果,代码如下: ...

  6. java双引号的转义字符_好程序员Java教程分享常见的转义字符

    原标题:好程序员Java教程分享常见的转义字符 好程序员Java教程分享常见的转义字符,在Java字符常量中,反斜杠(\)是一个特殊的字符,被称为转义字符,它的作用是用来转义后面一个字符.转义后的字符 ...

  7. javaweb模板_好程序员Java教程分享javaweb框架

    好程序员Java教程分享javaweb框架:Java是开源的,框架很多,这些框架都能解决特定的问题,提高开发效率.简化我们的代码复杂度,现在除了很多大家通用的一些主流框架外,很多公司针对自己的业务会自 ...

  8. java中forward和redirect_好程序员Java教程分享:Forward和Redirect的区别

    Java教程分享:Forward和Redirect的区别,用户向服务器发送了一次HTTP请求,该请求可能会经过多个信息资源处理以后才返回给用户,各个信息资源使用请求转发机制相互转发请求,但是用户是感觉 ...

  9. 好程序员Java培训分享如何快速入门Java编程

    好程序员Java培训分享如何快速入门Java编程,作为老牌编程语言,Java拥有广阔的市场应用,企业对Java人才的需求一直居高不下.有很多非专业.零基础的人想要学习Java却不知道怎么快速入门,接下 ...

最新文章

  1. redis在php中的使用介绍
  2. 用C++ 和OpenCV 实现视频目标检测(YOLOv4模型)
  3. springboot 整合jsp过程中的一些问题
  4. layui jquery ajax,url,type,async,dataType,data
  5. 程序中 设置jvm 参数_高效应用程序的7个JVM参数
  6. Leetcode 08. 字符串转换整数 (atoi)
  7. 前端学习(2482):关于接口的调错
  8. java byte(字节_Java字节序,java整型数与网络字节序 byte[] 数组转换关系(ByteArrayOutpu......
  9. 2006年星座运势全解-射手
  10. (Object detection)目标检测从入门到精通——第三部分非极大抑制
  11. 计算机绘图的教学目的,浅谈如何提高《计算机绘图AutoCAD》课程的教学质量
  12. 如何自己制作身份证扫描件?
  13. 可汗学院教学课程总目录
  14. 41款非常有创意的卡通图标大全可爱
  15. 北邮矩阵论- 第1章 1.3两个特殊的线性空间
  16. 【2020春招记录】 吉比特游戏研发笔试
  17. 荣耀MagicBook X桌面频繁蓝屏如何重装系统?
  18. 树莓派计算器c语言,树莓派与Python实验9——Tkinter计算器实验
  19. 砥砺前行!华为构建开放共赢云生态
  20. 内存使用占比存储到csv中加上时间

热门文章

  1. log4j 超完美配置文件!
  2. RHEL中的arp命令。
  3. Linux 基本网络配置 实验手册
  4. 28天打造专业红客(一)
  5. 都说 HashMap 是线程不安全的,到底体现在哪儿?
  6. Scala单例对象(伴生对象)
  7. jieba分词中cut和lcut的区别
  8. Hibernate 查询数据库中的数据
  9. Ubuntu安装软件失败
  10. 【java下午茶系列】java三重奏之封装