JVM垃圾收集——概述

文章目录

  • 1、什么是垃圾
  • 2、为什么需要垃圾收集
  • 3、如何进行垃圾收集
    • 3.1、早期垃圾收集
    • 3.2、Java垃圾收集机制
  • 4、小结

垃圾收集(Garbage Collection,GC)并不是Java语言所独有的,早在1960年,Lisp语言中就已经开始使用内存的动态分配和垃圾收集技术。可见,在很早以前,程序运行中产生的垃圾如何处理就已经引起了开发人员的重视。

1、什么是垃圾

前面已经提过,垃圾收集技术并不是Java语言所独有的,如今垃圾收集技术已经是现代开发语言的标配了。但垃圾收集技术却是Java语言的招牌能力,其优秀的垃圾收集机制极大地提高了开发效率。即使经过长时间的发展,Java的垃圾收集机制仍在不断演进变化,这是因为,不同的设备、不同的应用场景,对垃圾收集机制提出了更高的挑战。想要搞清楚垃圾收集机制,首先要弄清楚第一个问题:什么是垃圾?

在Java官网中,对垃圾的定义为:“An object is considered garbage when it can no longer be reached from any pointer in the running program.”意思是,在运行的程序中,当一个对象没有任何指针指向它时,它就会被视为垃圾。

由此可以看出,判断一个对象是否为垃圾对象的关键标准就是是否有指针指向它。当一个对象没有任何指针指向它时,即说明该对象不再被引用。如果一个对象不被引用之后还继续留在内存中,被占用的空间也无法被其他对象使用,如果这些垃圾对象所占用的空间一直保留至程序结束,随着垃圾对象越来越多,将可能导致内存溢出。对这种垃圾对象的清理就类似于我们熟悉的磁盘碎片整理,通过定时清理磁盘中的垃圾碎片,可以有效提升空间利用率。

那么,如何判断一个对象是否有指针指向它呢?关于这一问题,开发人员有很多探讨,诞生了众多对象存活判定算法。

2、为什么需要垃圾收集

对于高级语言来说,一个基本认知是如果不进行垃圾收集,内存迟早都会被消耗完。因为不断地分配内存空间而不进行回收,就好像不停地生产生活,而从来不打扫垃圾一样。

垃圾对象可能散列在任意位置,它所占用的内存被回收后,就会出现零零散散的空位,这些零散的内存利用率是很低的,当需要申请一个较大对象的内存时,可能出现找不到一整块连续的可用的存储空间,所以垃圾收集不仅是把垃圾对象所占用的内存进行回收,还涉及内存的整理。这就好比生活中的清洁、整理等家务,不仅要把垃圾扔掉,还要对物品进行规整,重新摆放,才能让家里看起来更干净整洁、空间利用率更高。

随着应用程序所应付的业务越来越庞大、复杂,用户越来越多,没有垃圾收集就不能保证应用程序的正常进行。

3、如何进行垃圾收集

3.1、早期垃圾收集

那如何进行垃圾收集呢?在早期的C/C++时代,垃圾收集基本上是手工进行的。开发人员使用new关键字申请内存,使用delete关键字释放内存。以下是C++里面申请和释放内存的代码。
在这里插入图片描述
这种方式可以灵活决定内存释放的时间,但是却给开发人员带来了很大的负担。因为开发人员必须在代码中频繁申请内存和释放内存,倘若有一些对象由于程序员的编码疏忽,忘记了释放内存,这些垃圾对象永远没有被清除,随着系统运行时间的不断增长,垃圾对象所耗内存可能持续上升,直至出现内存溢出,造成应用程序崩溃。

在有了垃圾收集机制可以自动回收垃圾对象的内存后,上述代码极有可能变成下面这样,不需要再去手动释放内存,等待回收机制自动处理即可:

     MibBridge *pBridge = new cmBaseGroupBridge();pBridge->Register(kDestroy);

现在,除了Java以外,C#、Python、Ruby等语言都使用了自动垃圾收集的思想,这也是未来的发展趋势。可以说,这种自动化的内存分配和垃圾收集的方式已经成为现代开发语言的标配。

3.2、Java垃圾收集机制

Java使用的是自动内存管理机制,有内存分配器和垃圾收集器来代为分配和回收内存。自动内存管理机制使开发人员无须参与内存的分配和回收,将开发人员从繁重的内存管理工作中解放出来,同时降低了内存泄漏和内存溢出的风险。

但是对于Java开发人员来说,自动内存管理就像一个黑匣子,如果过度依赖它,将会弱化开发人员在程序出现内存溢出等问题时定位和解决问题的能力。所以,了解JVM的自动内存分配和垃圾收集机制就显得非常重要,只有在真正了解JVM是如何管理内存后,我们才能够在遇见OutOfMemoryError问题时,快速地根据错误异常日志定位并解决问题。

如下图所示:
在这里插入图片描述
Java的垃圾收集机制主要作用于运行时数据区中的堆和方法区(图中的虚线区域)。其中,堆是垃圾收集器的工作重点。

Java的垃圾收集机制中有两个十分重要的概念,也是我们需要重点了解和学习的,分别是垃圾收集算法和分代算法。

在JVM中,垃圾收集算法主要有以下三种:

  • 标记-清除算法。
  • 复制算法。
  • 标记压缩算法。

这三种算法主要解决了将垃圾标记出来之后如何清除的问题。三种算法各有利弊,单独采用其中任何一种算法,都不能取得很好的效果。所以在JVM中,会针对内存的不同区域采用不同的垃圾收集算法,这就是分代算法。具体的内存区域如何划分,不同分区又需要采取何种垃圾收集算法。

4、小结

什么是垃圾?没有任何有效引用指向的对象就是垃圾。为什么要进行垃圾收集?提高内存的利用率,降低内存泄漏和内存溢出的风险,减少程序员的代码负担。收集哪里的垃圾?Java虚拟机运行时堆和方法区内存。谁来进行垃圾收集?垃圾收集器。如何进行垃圾收集?不同的区域使用不同垃圾收集算法的分代处理。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/771246.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

基于SSM框架的酒店预订系统

基于SSM框架的酒店预订系统的设计与实现 摘要 当今世界的互联网信息技术飞速发展,网络化的工作模式已经几乎覆盖到各个工作领域中的业务内,人们的日常生活也渐渐离不开互联网。因此,在当下全国各处的酒店都开始构建起了自己的网络预订系统。…

Spring Boot整合Spring Security

Spring Boot 专栏:Spring Boot 从零单排 Spring Cloud 专栏:Spring Cloud 从零单排 GitHub:SpringBootDemo Gitee:SpringBootDemo Spring Security是针对Spring项目的安全框架,也是Spring Boot底层安全模块的默认技术…

Netty学习——源码篇6 Pipeline设计原理

1 Pipeline设计原理 在Netty中每个Channel都有且仅有一个ChannelPipeline与之对应,它们的组成关系如下图: 通过上图可以看到,一个Channel包含了一个ChannelPipeline,而ChannelPipeline中又维护了一个由ChannelHandlerContext组成的…

【笔记】深入理解JVM机制

🎥 个人主页:Dikz12📕格言:吾愚多不敏,而愿加学欢迎大家👍点赞✍评论⭐收藏 目录 JVM 运⾏流程图 JVM 中内存区域划分 方法区 / 元数据区 堆 栈 程序计数器 本地方法栈 内存区域总结 JVM 中类加载过程 …

C++ STL- list 的使用以及练习

目录 0.引言 1. list 介绍 2. list 使用 2.1 构造函数 2.2 list iterator 的使用 3 list capacity 4. list element access 5. list modifiers 6. list 迭代器失效 7. list 与vector 对vector 8. OJ 题讲解 删除链表的倒数第 N 个节点: 0.引言 …

Jetson AGX ORIN 配置 FGVC-PIM 神经网络(包含 arm64 下面 torch 和 torchvision 配置内容)

Jetson AGX ORIN 配置 FGVC-PIM 神经网络 文章目录 Jetson AGX ORIN 配置 FGVC-PIM 神经网络配置 ORIN 环境创建 FGVC-PIM 虚拟环境安装 PyTorch安装 torchvision安装其他依赖包 配置 ORIN 环境 首先先配置 ORIN 的环境,可以参考这个链接: Jetson AGX …

Go第三方框架--gin框架(一)

序言 Gin框架作为go语言使用最多的web框架,以其快速的响应速度和对复杂http路由配置的支持受到程序员和媛们的喜爱,几乎统治了web市场。但作为一名合格的程序员,要知其然更要知其所以然,不然八股文背的也没有啥意思。本着这个原则…

JavaScript中的Lexical Environment

概要 本文主要介绍JavaScript中的一个重要概念Lexical Environment,它可以帮助我们解释我们为什么可以通过嵌套方法,共享数据,以及为什么可以在函数中定义一个和全局变量同名的变量,并且不会影响到全局变量。 基本分析 基本概念…

28377s使用的记录和注意点(1)

28377s使用的记录和注意点(1)_dsp28377设置复位不清除ram区域-CSDN博客

SUB-1G替代CMT2380F32 SOC芯片DP4306F 32 位ARM Cortex-M0+内核应用无线遥控工控设备智能家居

DP4306F是一款高性能低功耗的单片集成收发机,集成MO核MCU,工作频率可覆盖200MHiz^ 1000MHz。 支持230/408/433/470/868/915频段。该芯片集成了射频接收器、射频发射器、频率综合器、GFSK调制器、GFSK解调器等功能模块。通过SPI接口可以对输出功率、频道选…

如何使用Python进行网络安全与密码学【第149篇—密码学】

👽发现宝藏 前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。【点击进入巨牛的人工智能学习网站】。 用Python进行网络安全与密码学:技术实践指南 随着互联网的普及,网络…

几个常用的AI工具

人工智能大模型的出现对人类社会产生了深远的影响,这些影响既包括积极的方面,也包括一些潜在的挑战: 1. **提高效率**:AI大模型能够快速处理大量数据,提高工作效率,尤其在数据分析、自然语言处理等领域。 2. **辅助决…

面向对象【枚举类】

文章目录 枚举类定义枚举类enum 方式定义的要求和特点 enum 中常用方法实现接口的枚举类 枚举类 枚举类是一种特殊的类,它用于定义一组固定数量的常量。枚举类在实际开发中非常有用,因为它们可以增加代码的可读性和可维护性。本文将介绍Java枚举类的定义…

spring maven项目 实时接口请求次数及时间发送到grafana监控_亲测成功

spring maven项目 实时接口请求次数及时间发送到grafana监控_亲测成功 说明: spring项目使用aop方式拿到请求接口uri,算出从请求到响应的耗时, 然后使用statsd包发送udp数据给grafana去展示. 完全不影响代码性能和稳定性,因为使用udp协议发送,就算grafana那边挂了,也不影响项…

【C++】6-2 交换函数2 分数 10

6-2 交换函数2 分数 10 全屏浏览 切换布局 作者 刘利 单位 惠州学院 根据题目需求&#xff0c;编写一个交换函数Swap。 裁判测试程序样例&#xff1a; #include <iostream> using namespace std; class pen{private:string brand;string color;double price;publi…

Java基于微信小程序的校园请假系统

博主介绍&#xff1a;✌程序员徐师兄、7年大厂程序员经历。全网粉丝15W、csdn博客专家、掘金/华为云//InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精彩专栏推荐订阅&#x1f447;&#…

【Java程序设计】【C00370】基于(JavaWeb)Springboot的公司进存销管理系统(有论文)

TOC 博主介绍&#xff1a;java高级开发&#xff0c;从事互联网行业六年&#xff0c;已经做了六年的毕业设计程序开发&#xff0c;开发过上千套毕业设计程序&#xff0c;博客中有上百套程序可供参考&#xff0c;欢迎共同交流学习。 项目简介 项目获取 &#x1f345;文末点击卡片…

OJ : 1090 :整数幂(多实例测试)

题目描述 求A^B的最后三位数表示的整数&#xff08;1<A,B<1000&#xff09; 输入 n个测试实例&#xff0c;每个实例给出两个正整数A,B 输出 输出A^B的最后三位&#xff08;没有前导0&#xff09; 样例输入 2 2 3 12 6 样例输出 8 984 思路&#xff1a; 这个题…

c# 更改网卡的默认网关

前言: 通过程序更改网卡网关 公司内有多个网络出口,其中一个为固定IP的 带宽只有60M用于应用系统访问, 一个是一条千兆带宽的ADSL,但是只有电信内网IP。做开发调试尤其是企业微信接口涉及到接口白名单IP&#xff0c;需要走固定IP&#xff0c;而日常一些下载当然我选择用千兆带宽…

视频记录历史播放位置效果

简介 每次打开页面视频从上一次的播放位置开始播放 利用lodash库做节流 代码 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-sca…