Java语言与C语言中垃圾回收的不同方式研究
2021-03-08胡宇涛
摘 要:计算机中的各项语言都具备特有的优缺点,其中Java语言属于对象语言的范畴,而C语言属于过程式语言。本文结合Java语言和C语言垃圾回收动态存储的基本特征,对它们不同的垃圾回收的方式进行探究,明确Java语言回收和操作的机制,掌握C语言中产生垃圾的原因、回收的原理以及具体方式。
关键词:Java语言;C语言;垃圾回收
引言:随着信息技术的高速发展,为了进一步提升计算机设备的运行速率,及时清除垃圾信息,扩大系统的存储量,编程人员应该合理地应用编程语言。垃圾回收技术具有较强的使用价值,能在特定的算法中对资源进行回收。不同的编程语言具有不同的垃圾回收模式,比如Java语言和C语言这两者间就存在一定差异。
一、Java语言中垃圾回收的方式
(一)垃圾回收方式
在Java语言可以使用垃圾回收器进行垃圾处理,它的指针具有严格的构建和应用制度。Java语言是C++语言的进一步优化,它内部结构更加地简化,摒弃多重继承体制中的要素。对垃圾回收器和垃圾收集进行简单的探究。回收器采用动态化运作的模式,可以自动解放内存块,并对其进行压缩。它是一个低层次的运行线,程序员的控制对它的运行情况没有明显的影响。垃圾收集是一种自动性操作,只能回收那些不被程序占用的部分。它只能在有需求的情况下进行。
(二)操作机制
第一,跟踪算法。这种算法的操作为以根部为出发点对系统进行全方位的扫描和内存块识别,判断其是否处于可达状态,如果发生环形引用的情况,数据的计数的数值一直无法达到0,这样垃圾就不能被回收。在这种情况下,跟踪算法能对指针指向的内存块进行标记,及时清除可以释放的区块,实现回收垃圾的目的。第二,复制算法。在最初的阶段,把堆分为一个对象面和多个空闲面,程序在运行中占据对象面的空间。利用这种方法可以把对象面的内容复制到空闲面,及时程序的空间处于充满的状态也能进行复制。这样就能实现面与面的互换,但是不能对垃圾进行回收[1]。复制算法在压缩问题中能发挥重要的作用,通过互换的模式,释放对象面的空间。
第三,分代算法。它是复制算法的进一步优化,能提升操作的效率,避免程序暂停时间过长的问题。分代算法在大部分程序中都能够有效地应用,能把堆分为多个组别。之后利用垃圾收集器把需要处理的内存块转移到最高级别的子堆中,从而提升操作的效率。第四,引用计数算法。在内存块原有的基础上新配置一个引用计数,只要这新内存块被原有内存块和外面的指针引用时,它的计数就增加一个数值。反之释放一个,数值就会减少一个。直到引用计数为0时,就可以对这个内存块进行回收。第五,压缩算法。对所有内存块移到堆中进行处理,把原来的区域变成空闲的位置,并及时进行更新。第六,自适应算法。它需要根据实际的情况,选用对应的模式进行垃圾处理操作。
二、C语言中垃圾回收的方式
C语言能够与操作系统进行直接地交互,不具备运行时库。因为运行时库能够对内存进行压缩,减少堆栈占据的空间。所以C语言要想压缩空间就需要编程人员进行直接操作。
(一)垃圾产生的原因
在C语言中,主要有三种内存分配的模式。第一,在栈上构建局部变量。比如,void func(int p1, int p2, int p3){int a = p1;int b =p2;int c =p3}。第二,静态区域分配。比如,void swipe(int** p){int temp=999;*p=&temp;}。第三,动态区域分配。在进行分配时,通过calloc进行申请,在free的作用下进行释放。这种方法相对与其它两种模式更加方便,能够在大型程序编写中发挥重要的内存分配作用。但是它存在一定的使用风险,即通过calloc进行申请时,其中的动态内存主要由另外的函数进行使用,程序员在操作中经常用free进行内存释放,这就导致这部分内容一直处于被分配的情况,增强系统内部不足问题发生的概率。此外在这种模式下,无法判定内存泄露的具体位置。C语言中的这些内存块就是垃圾,在操作中需要应用垃圾收集器,它具动态存储的功能,能把垃圾回收到空闲链接中。
(二)回收的原理
C语言垃圾回收的历史最早起源于上世纪60年代的Lisp语言,这项语言主要依靠动态分配进行运作在,语言都在堆上进行分配。程序员需要掌握一种模式能对其进行动态监管,这样才能实现释放内存的目的,所以垃圾回收技术应运而生。C语言的垃圾回收模块有三个运行要求:不存在内存泄露的问题、可以及时回收没有使用的内存、可以对内部进行整理和缩减。在程序中已经分配的内存都有明确的指向,如果某一块内存不存在指向,这种情况就被称为内存泄露,即处于不可达的状态。当程序处于任意状态时,静态数据段、程序栈以及寄存器中指针的集合体被称为根集。可达主要以根集为指引,能找到指向它的指针,反之就是不可达[2]。
垃圾回收器在运行时先以根集为基础,根据指针所指的方向进行扫描,当找到可以存储的空间后先进行标记。其次对整个内存进行扫描,再次进行标记操作。最后在完成扫描工作后,需要对所有的内存块进行探究,如果有的内部块没有被标记,说明它在链表中没有发挥作用,可以进行收回。
(三)垃圾回收方式
现阶段,C语言中垃圾处理的主要模式为:标记清除法以及引用计数法。第一,标记清除法。这种清除模式起源于Lisp语言,主要分为两个操作阶段:空间标记和垃圾清除。在进行空间标记时,利用垃圾回收器对每个内存块进行扫描,标记引用的区域。在完成整体扫描之后,要对内存集中的所有内存进行探究,回收没有标记的内存块。应用标记清除法的关键点在于应该准确标记被引用的内存块。在进行垃圾清除时,被标记的对象对称为可达对象,没有被标记的就是不可达,即需要清除的垃圾。这时就需要按照次序释放内存块中的内存,对所有没有标记的进行清除。第二,引用计数法。在内存块原有的基础上新配置一个引用计数,只要这新内存块被原有内存块和外面的指针引用时,它的计数就增加一个数值,如果指针对其进行释放,它的计数就减少一个数值。当它的计数数值为0时,就需要清除这个内存块对其中的存储空间进行重新利用。当这种方法需要配置两个函数时,可以同时进行增加和减少计数的操作,数值为0时进行内存释放。
引用计数法在应用时不会干扰程序的运行,并且具有较好的局部性。但是存在环形引用的情况,并且在释放存储空间时,需要计算引用的数值。标记清除法不涉及环形引用的问题,并且引用计数的效率较高。但是在操作中需要暂停程序,存在一定的时间损耗。
結论:综上所述,Java语言和C语言它们具有不同的垃圾回收模式,但是无论在哪一种语言中,垃圾处理工作都发挥着不可或缺的作用。所以在进行编程学习时,特别是在入门的阶段更需要培养释放函数的习惯,保障每次使用后都能释放内存,这样既能提升空间的利用率,又能保障系统的运转效果。
参考文献:
[1]杨明.C语言与汇编语言相结合实现STM32F107单片机复位方法研究[J].建井技术,2020,41(01):44-46.
[2]沈逸飞,任春龙,胡云飞,等.浅析C语言、Java、Python的数组合并方法[J].电脑知识与技术,2020,16(03):78-82.
作者简介:
胡宇涛,男,民族:汉,出生年月1999-03-20,籍贯:湖南郴州, 学历:本科,研究方向:软件工程(java、前端、C语言)