前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >垃圾回收器的基本原理

垃圾回收器的基本原理

原创
作者头像
疯狂的KK
发布于 2023-07-13 09:16:16
发布于 2023-07-13 09:16:16
2870
举报
文章被收录于专栏:Java项目实战Java项目实战

垃圾回收器的基本原理

推荐阅读

【玩转 GPU】AI绘画、AI文本、AI翻译、GPU点亮AI想象空间-腾讯云开发者社区-腾讯云 (tencent.com)

腾讯云玩转Stable Diffusion 模型-腾讯云开发者社区-腾讯云 (tencent.com)

垃圾回收器(Garbage Collector)是Java虚拟机(JVM)中的组件,负责自动管理动态分配的内存,回收不再被程序使用的内存空间,从而避免内存泄漏和内存溢出的问题。垃圾回收器的基本原理包括垃圾识别和垃圾回收两个步骤。

垃圾识别

垃圾回收器通过标记-清除算法(Mark and Sweep)来识别哪些对象是垃圾。该算法的基本思想是,从根对象(如栈帧中的局部变量和静态变量)出发,递归地遍历所有可达的对象,并将其标记为“活动对象”。未标记的对象则被认为是垃圾,可以被回收。

在并发垃圾回收的情况下,可能会存在对象引用关系的动态变化,为了解决这个问题,通常采用可达性分析(Reachability Analysis)来实现垃圾识别。可达性分析基于程序栈和程序计数器的状态,确定对象之间的引用关系,将不可达的对象标记为垃圾。

垃圾回收

垃圾回收是指清理和回收被标记为垃圾的对象的过程。垃圾回收器会根据一定的策略,回收内存中的垃圾,并将空闲的内存空间合并形成连续的内存块,以供后续的对象分配使用。

常见的垃圾回收算法有标记-清除算法、复制算法、标记-整理算法和分代收集算法等。其中,标记-清除算法是最基本的垃圾回收算法,但它的效率较低,会产生内存碎片。为了解决这个问题,复制算法将内存分成两个区域,分别用作对象的分配和回收。标记-整理算法则是在标记-清除算法的基础上,将存活的对象移到内存的一端,从而整理出连续的空闲内存区域。

垃圾回收器的实现

垃圾回收器有两种主要的实现方式:串行垃圾回收器和并行垃圾回收器。

串行垃圾回收器(Serial Garbage Collector)是最简单的垃圾回收器,它会与应用程序的执行交替进行。在垃圾回收时,应用程序的执行会暂停,只有垃圾回收器在运行。这种垃圾回收器适用于单核处理器的环境。

并行垃圾回收器(Parallel Garbage Collector)利用多个线程来加速垃圾回收的过程。在垃圾回收时,多个垃圾回收线程会并发地扫描和回收内存,同时应用程序的执行也会继续进行。这种垃圾回收器适用于多核处理器的环境,可以充分利用多核处理器的计算能力,提高垃圾回收的效率。

垃圾回收器的回收时机

垃圾回收器不能及时回收内存,因为其回收时机是由Java虚拟机来决定的。Java虚拟机会根据一定的策略来判断何时触发垃圾回收,常见的触发条件包括:

  1. 当内存达到一定的阈值时,触发垃圾回收。Java虚拟机会根据内存的使用情况,设置一个阈值(如堆内存使用的百分比),当内存使用超过这个阈值时,就会触发垃圾回收。
  2. 当对象分配速度超过垃圾回收速度时,触发垃圾回收。如果应用程序频繁地分配内存,而垃圾回收的速度无法跟上分配的速度,就会导致内存的使用越来越高。为了避免内存溢出,Java虚拟机会在这种情况下触发垃圾回收。
  3. 当系统空闲时,触发垃圾回收。如果系统处于空闲状态,没有其他重要的任务需要执行,Java虚拟机会利用这个时间窗口来进行垃圾回收,以尽可能地回收内存。
  4. 调用System.gc()方法手动触发垃圾回收。虽然调用该方法不能保证立即触发垃圾回收,但可以向Java虚拟机发送一个建议,在合适的时机进行垃圾回收。

主动通知虚拟机进行垃圾回收

除了上述的垃圾回收器的回收时机,还可以通过一些手段主动通知虚拟机进行垃圾回收。

  1. 调用System.gc()方法。尽管这个方法只是向虚拟机发送一个垃圾回收建议,并不能保证立即触发垃圾回收,但是在某些情况下,虚拟机会根据建议来进行相应的操作。
  2. 调用Runtime.getRuntime().runFinalization()方法。这个方法会强制虚拟机在适当的时候调用那些被对象的finalize()方法声明的清理操作。
  3. 使用对象的WeakReference或SoftReference。弱引用(Weak Reference)和软引用(Soft Reference)是Java中用于管理内存的引用类型。通过使用这些引用类型,可以在内存不足时,让虚拟机主动回收被引用的对象。
  4. 调整垃圾回收器的相关参数。可以通过调整垃圾回收器的参数,以控制垃圾回收的时机和行为。例如,通过设置-Xmx参数来调整堆的大小,通过设置-XX:+UseConcMarkSweepGC参数来选择使用并发垃圾回收器。

需要注意的是,尽管可以通过这些手段来主动通知虚拟机进行垃圾回收,但并不能保证立即回收内存。垃圾回收的具体时机还是由虚拟机根据内部策略来决定。因此,在编写Java程序时,应该尽量避免过度依赖垃圾回收机制,合理管理对象的生命周期,以提高程序的性能和稳定性。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
《流畅的Python》第六章学习笔记
策略模式:定义一系列算法,把他们一一封装起来,并且使它们可以相互替换。本模式使得算法可以独立于使用它的客户而变化。
zx钟
2020/12/24
5940
一起来探讨 python 类爆炸问题
由于您不必从特定的类派生对象就可以被程序重用,因此您可能会问为什么应该使用继承而不是仅实现所需的接口。以下规则可能对您有帮助
公众号---人生代码
2020/05/17
6410
Python学习笔记整理(十六) 类的设计
如何使用类来对有用的对象进行建模? 一、Python和OOP Python和OOP实现可以概括为三个概念。 继承     继承是基于Python中属性查找(在X.name表达式中) 多态     在X.method方法中,method的意义取决于X的类型(类) 封装     方法和运算符实现行为,数据隐藏默认是一种惯例。 封装指的是在Python中打包,也就是把实现的细节隐藏在对象接口之后。这并不代表有强制的私有性。封装可以让对象接口的现实 出现变动时,不影响这个对象的用户。 1、不要通过调用标记进行重载 不要在同一个类中对同一个方法名定义两次,后面的会覆盖前面,也不要对对象类型进行测试。应该把程序代码写成预期的对象接口。而不是特定类型的数据类型。 2、类作为记录 通过类的实例来创建多个记录。 3、类和继承:是“一个”关系 (is a) 从程序员的角度来看,继承是由属性点号运算启动的,由此触发实例,类以及任何超类中变量名搜索。 从设计师的角度看,继承是一种定义集合成员关系的方式:类定义了一组内容属性,可由更具体的集合(子类)继承和定制。 子类和超类的继承是1对1的关系. PizzaRobot是一种Chef,Chef是一种Employee.以OOP术语来看,我们称这些关系为“是一个连接”(is a):机器人是个主厨,主厨是一个员工。 class Employee:         def __init__(self,name,salary=0):                 self.name=name                 self.salary=salary         def giveRaise(self,percent):                 self.salary=self.salary+(self.salary*percent)         def work(self):                 print self.name,"does stuff"         def __repr__(self):                 return "<Employee:name=%s,salary=%s>" % (self.name,self.salary) class Chef(Employee):         def __init__(self,name):                 Employee.__init__(self,name,5000)         def work(self):                 print self.name,"make food" class Server(Employee):         def __init__(self,name):                 Employee.__init__(self,name,40000)         def work(self):                 print self.name,"interface with customer" class PizzaRobot(Chef):            def __init__(self,name):#有点想不明白,既然继承就够了,为什么还要在这里构造                 Chef.__init__(self,name)    #Chef.__init__(self,name) =》Employee.__init__(self,name,5000)=>__init__(self,name,salary=0)         def work(self):                 print self.name,"make pizza" if __name__=='__main__':         bob=PizzaRobot('bob')         print bob         bob.work()         bob.giveRaise(0.20)         print bob;print # python employees.py   <Employee:name=bob,salary=5000> bob make pizza <Employee:name=bob,salary=6000.0> 理解有问题的地方 class PizzaRobot(Chef):            def __init__(self,name):#有点想不明白,既然继承就够了,为什么还要在这里构造,下面拿掉这里做对比   
py3study
2020/01/09
7470
Python基础-9 类
类中的概念比较多,初学者掌握面向对象、定义和使用类、单继承、类变量和实例变量即可。迭代器和生成器是Python中迭代利器,推荐掌握。
一只大鸽子
2022/12/06
3780
Python——编写类装饰器
类装饰器类似于函数装饰器的概念,但它应用于类,它们可以用于管理类自身,或者用来拦截实例创建调用以管理实例。
py3study
2020/01/06
7160
Python 如何优雅的操作 PyMySQL
在使用Python操作MySQL数据过的过程中,基本的增删改查操作如何更加高效优雅的执行。这里将以PyMySQL为例,介绍一下如何使用Python操作数据库。 Python对MySQL数据库进行操作,基本思路是先连接数据库 Connection 对象,建立游标 Cursor 对象,然后执行SQL语句对数据库进行操作,获取执行结果,最终断开连接。大致过程是这样,在对其进行介绍之前,先介绍一些基本的概念。
luckpunk
2023/09/29
7650
Python 如何优雅的操作 PyMySQL
再再肝3天,整理了70个Python面向对象编程案例
Python 作为一门面向对象编程语言,常用的面向对象知识怎么能不清楚呢,今天就来分享一波
周萝卜
2021/11/24
7340
python笔记:面向对象
1 封装与断言 在Python中,用类封装概念十分简单,下面是一个类的使用。所有的类都继承自object。在类的成员函数中,第一个参数必须是self,否则,这个函数就会变成类似java中的“静态函数”。__init__是构造函数,里面可以随意的定义类的属性。
超级大猪
2019/11/22
4070
Python:Python学习总结
PHP的$和->让人输入的手疼(PHP确实非常简洁和强大,适合WEB编程),Ruby的#、@、@@也好不到哪里(OO人员最该学习的一门语言)。
全栈程序员站长
2022/09/08
5800
Python:Python学习总结
Python学习笔记整理(十五)类的编写
类代码编写细节 一、class语句 一般形式 class    <name>(superclass,...):     data=value     def mothod(self,...):         self.member=value 在class语句内,任何赋值语句都会产生类属性。 类几乎就是命名空间,也就是定义变量名(属性)的工具,把数据和逻辑导出给客户端。 怎么样从class语句得到命名空间的呢? 过程如下。就像模块文件,位于class语句主体中的语句会建立起属性。当py
py3study
2020/01/08
9640
Python3.6学习笔记(三)
面向对象编程 Object Oriented Programming 简称 OOP,是一种程序设计思想。OOP把对象作为程序的基本单元,一个对象包含了数据和操作数据的函数。
大江小浪
2018/09/19
3990
Python3.6学习笔记(三)
python 实现多继承
python是少数支持多重继承的现代编程语言之一。多重继承是同时从多个基类派生一个类的能力
公众号---人生代码
2020/05/18
7210
3.Python3基础入门学习笔记(三)
描述: 我们所知道常用的操作系统有Windows,Mac,LINUX,UNIX,这些操作系统底层对于文件系统的访问工作原理是不一样的,因此您可能要针对不同的操作系统来考虑使用那些系统模块,即修改不同的代码。但是Python中有了OS模块,我们不需要关心什么操作系统下使用什么模块,OS模块会帮你选择正确的模块并调用。
全栈工程师修炼指南
2022/09/28
3790
3.Python3基础入门学习笔记(三)
Python Class Attributes: An Overly Thorough Guide
I had a programming interview recently, a phone-screen in which we used a collaborative text editor.
WindCoder
2018/09/19
4830
Python Class Attributes: An Overly Thorough Guide
灵活的设计组合
组合比继承更灵活,因为它可以建模松散耦合的关系。对组件类的更改对复合类影响很小或没有影响。基于组成的设计更适合更改
公众号---人生代码
2020/05/18
4580
python学习笔记(10)python面向对象(一)类的创建实战
在python中使用class语句来创建一个类,class之后为类的名称并以冒号结尾,例子如下:
大数据小禅
2021/08/16
3880
python练习题-day27
1、写一个类,用来将浮点型值转换成金额。在本练习里,我们使用美国货币,但读者也可以自选任意货币。
10JQKA
2019/10/23
4160
Python内置工具(tools)总结
除此之外,还有一些其他工具,比如mimetools、unittest等,上述四个tools作用于内建类型和函数、类等,比较通用,也较为常用。 -operator : 内置的操作符模块 -collections : 简化容器类型的一些操作和使用 -itertools : 可迭代类型工具 -functools : 函数工具,尤其是装饰器
py3study
2020/01/08
2K0
python学习笔记13-python面
创建对象的过程称之为实例化,当一个对象被创建后,包含三个方面的特性,对象句柄,属性和方法
py3study
2020/01/15
9160
Python编程思想(27):类的继承
继承是面向对象的3大特征之一(另两个特性是封装和组合),也是实现软件复用的重要手段。Python的继承是多继承机制,也就是一个子类可以同时有多个直接父类。
蒙娜丽宁
2020/07/02
1.3K0
相关推荐
《流畅的Python》第六章学习笔记
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档