Java老师在期末复习大纲上出了一道关于JVM垃圾回收机制的题目,想要我们简述一下JVM垃圾回收机制,与老师交流后,大概老师是希望通过与其他语言在垃圾回收对比,介绍一下Java在这方面的特点和处理过程,这里我搜索到一篇差不多内容的论文,这篇论文在内容上讲的很浅,没有深入到源码和内部算法,大致了解一下即可。
 
      在运用面向对象语言编写的程序中,当某些对象不再被引用的时候,内存回收它占领的空间,以便空间能够被后来的新对象所使用,以免造成内存泄露。C++与 Java 是这些年较为流行的面向对象语言,Java是由 C++发展出来的。 内存泄漏一般来讲主要有两种情况:第一种情况是在堆中分配的内存,在没有将其释放的时候,就将能访问这块内存的方式删掉;第二种情况是在内存对象已经不需要的时候,仍旧保留着内存和它的访问方式。 而出现第一种情况多是在 C++中,指针是C++中一种内置的数据类型,且发生的原因是所使用的指针出现了重新赋值的情况;第二种情况多出现在 Java 中,这也是 Java 内存泄露的主要情况。
   垃圾回收机制是一种动态的存储技术,它能够自动释放不再被程序引用的对象,按照特定的垃圾回收算法实现系统资源自动回收的功能。
Java 是一种跨平台,适合于分布式计算环境的纯面向对象编程语言。 在 Java 中,程序员是通过关键字 new 来创建对象以及在堆(Heap)中为对象分配内存空间(基本数据类型除外),而对象的释放是由 GC(Garbage Collection,垃圾回收器)决定和执行的。这种收支两条线在很大程度上简化了程序员的工作, 但 也 加 重 了 JVM (Java VirtualMachine,Java 虚拟机)的工作。 Java 并没有明确指明 JVM 在进行垃圾回收时使用哪种垃圾回收算法,但是不管采用那种垃圾回收算法均要完成发现无用对象并回收被无用对象占用的内存空间的功能。 Java 中对内存对象的访问采用的是引用方式,当 GC 跟踪到某个对象没有被
任何线程访问时,该对象就要被删除,就将其加入到垃圾回收队列,但是进行垃圾回收的线程是一种低优先级的系统级线程,为此系统并不会马上进行对象的消除, 而何时消除并释放内存是无法预知的。 在Java 中一般是在 CPU 空闲或者是空间不足时自动进行垃圾回收,对于程序员来讲, 是无法精准的控制垃圾回收的时机和回收的顺序,哪怕是 Java 虚拟机抛出 OutOfMemoryError 异常, 或者是程序员调用了System.gc()方法请求 JVM 进行垃圾回收。
       C++也是一种面向对象语言,但由于兼容了 C 我们通常认为它是一种半面向对象语言。 在 C++中内存的分配主要有三种方法:1)全局变量和静态变量存储在静态存储区中,生存的周期就是程序运行的周期,即当程序结束,才释放这些存储空间;2)函数内部的局部变量存储在栈上,生存的周期就是该变量所在函数的运行周期,即函数调用结束后,这些存储空间自动释放。3)动态分配存储空间,在 C 语言中通过malloc,free 来完成内存空间的分配与释放, 在 C++中通过 new,delete来完成内存空间的分配与释放, 生存周期是由 new 和 delete 来决定的。
在 C++中程序员运用 new 实现动态分配内存空间,分配后就需要负责这块内存的整个生命周期。 从分配到使用再到最后的释放,这样的过程显的很灵活,但同时也十分繁琐,程序员很容易由于某种原因而忘记释放内存,从而导致内存的泄露。 而 C++不像 Java 那样有 GC自动实现垃圾回收,但为我们提供了智能指针来解决内存问题。 智能指针是一种像指针的 C++对象,它能够在对象不使用的时候自己销毁掉。
       在 C++标准库(std)中提供了一种智能指针 auto_ptr,实际上该智能指针是一种模板类,其工作原理是:通过 new 来分配内存空间构造一个对象,通过自动调用析构函数来完成对这段内存的释放。 具体的实现是:auto_ptr 在构造时获取对某个对象的所有权,在析构时释放该对象,这样可以提高代码的安全性。
例如:
int * p=new int();
auto_ptrap(p);

智能指针 ap 获取了 p 的所有权, 从此我们不必关心应该何时释放 p, 更不用担心发生异常会有内存泄漏。 auto_ptr 智能指针使用简单,方便灵活,除了在定义的时候与普通指针有一点区别以外,其他具体的使用与普通指针是一样的,但是 auto_ptr 智能指针不能将数组作为参数以及不能将 auto_ptr 对象作为标准模板库(STL)容器的元素使得它的使用并不是很广泛。

Boost 库 是 为 C++语言标准库提供扩展的一些 C++程序库的 总称 ,Boost 库为我们定义了多个不同智能指针来 管理不同的场景 ,shared_ptr 是使用最广泛的智能指针。 shared_ptr 智能指针在内部维护一个引用计数器, 当有指针指向这块内存区域时引用计数器加 1,反之减 1, 若没有任何指针指向引用计数器为 0, 则释放内存区域。shared_ptr 指针可以实现共享和转移所有权, 同时它可以被 STL 的容器所使用,这一点与 auto_ptr 指针不同,还有一个更大的特点就是适合管理对象被若干个对象共享的复杂问题。 scoped_ptr 是 Boost 库中最简单的智能指针,当指针离开作用域时释放相关的资源,该指针不能共享指针的所有权也不能转移所有权,即内存地址只能给声明的变量使用而不能给其他使用。 Boost 库还有很多其他智能指针,这里不再一一叙述,总之在 C++中不论使用标准库中的智能指针,还是 Boost 库中的智能指针,在一定的条件下可以实现垃圾回收,同时智能指针使用起来比较简单,能够有效地解决内存泄露问题。
【参考文献】
[1]Java 内存分配与释放[OL]. http://wenku.baidu.com/view/c124098ccc22bcd126f
f0cd4.html.
[2]全面分析 Java 的垃圾回收机制[OL]. http://tech.qq.com/a/20060726/000329.htm.
[3]陈龙得,毕海滨.浅谈在 C++中如何实现垃圾自动回收[J].电脑知识与技术,
2008,7:2007-2008.
[4]C++Boost 库中的智能指针论 [OL]. http://blog.sina.com.cn/s/blog_6eb6c 4590
100n74y.html.
作者简介:王艳娟(1979—),女,济南职业学院教师。

浅析 Java 与 C++ 的垃圾回收机制的更多相关文章

  1. Java高级之虚拟机垃圾回收机制

    博客出自:http://blog.csdn.net/liuxian13183,转载注明出处! All Rights Reserved ! 区别于C语言手动回收,Java自动执行垃圾回收,但为了执行高效 ...

  2. java基础(一):谈谈java内存管理与垃圾回收机制

    看了很多java内存管理的文章或者博客,写的要么笼统,要么划分的不正确,且很多文章都千篇一律.例如部分地方将jvm笼统的分为堆.栈.程序计数器,这么分太过于笼统,无法清晰的阐述java的内存管理模型: ...

  3. java: system.gc()和垃圾回收机制finalize

    System.gc()和垃圾回收机制前的收尾方法:finalize(收尾机制) 程序退出时,为每个对象调用一次finalize方法,垃圾回收前的收尾方法 System.gc() 垃圾回收方法 clas ...

  4. java基础学习之垃圾回收机制

    回收过程: 1.发现无用的对象 2.回收无用对象占用的内存的空间. 垃圾回收相关算法: 1.引用计数法 堆中每个对象都有一个引用计数.被引用一次,计数加一.被引用变量值变为null,则计数减一. 到计 ...

  5. Java虚拟机(JVM)与垃圾回收机制(GC)的详解

    一.JVM结构 根据<java虚拟机规范>规定,JVM的基本结构一般如下图所示: 从左图可知,JVM主要包括四个部分: 1.类加载器(ClassLoader):在JVM启动时或者在类运行时 ...

  6. Java 内存分配及垃圾回收机制初探

    一.运行时内存分配 Java虚拟机在执行Java程序的过程中会把它所管理的内存划分为若干个不同的数据区域. 这些区域都有各自的用途,以及创建和销毁的时间,有的区域随着虚拟机进程的启动而存在,有些区域则 ...

  7. Java内存分配及垃圾回收机制(未完待待续)

    Java内存区域 1.内存区域 jvm运行时数据区域 程序计数器 Java虚拟机栈 本地方法栈 方法区 Java堆 大图 2.概念解释 程序计数器   线程私有的一块很小的内存空间,它是当前线程所执行 ...

  8. Java内存分配及垃圾回收机制

    Java内存区域 1.内存区域 jvm运行时数据区域 程序计数器 Java虚拟机栈 本地方法栈 方法区 Java堆 大图 2.概念解释 程序计数器   线程私有的一块很小的内存空间,它是当前线程所执行 ...

  9. 【转】Java虚拟机的JVM垃圾回收机制

    详见:http://blog.yemou.net/article/query/info/tytfjhfascvhzxcytp43       1.JVM内存空间     JVM堆(Heap)= 新生代 ...

随机推荐

  1. 在ensp上模拟企业网络场景并Access接口加入相应VLAN

    模拟的企业网络大概描述: 公司内网是一个大的局域网,二层交换机S1放置在一楼,在一楼办公的部门有IT部和人事部:二层交换机S2放置在二楼,在二楼办公的部门有市场部和研发部.由于交换机组成的是广播网,交 ...

  2. C#Windows Forms窗体、按钮-xdd

    1.更换窗体图标 方法:单击窗体,更改icon属性. 2.调整窗体打开时默认位置 方法:单击窗体,更改StartPotion属性. 3.修改窗体大小 方法:单击窗体,更改Size属性. 4.设置窗体的 ...

  3. 模型量化原理及tflite示例

    模型量化 什么是量化 模型的weights数据一般是float32的,量化即将他们转换为int8的.当然其实量化有很多种,主流是int8/fp16量化,其他的还有比如 二进制神经网络:在运行时具有二进 ...

  4. SpringBoot之DispatcherServlet详解及源码解析

    在使用SpringBoot之后,我们表面上已经无法直接看到DispatcherServlet的使用了.本篇文章,带大家从最初DispatcherServlet的使用开始到SpringBoot源码中Di ...

  5. Ztree树增删改查菜单,遇到的问题总结

    一.引言 我今天做了一个Ztree树增删改查菜单的功能.其中遇到了很多坑爹的问题,和大家讲述一下. 二.代码展示 1.Ztree树前台代码 <%@ page language="jav ...

  6. 【并发编程】关于Thread类的详细介绍

    多线程编程基础--Thread类 Thread类是Java中实现多线程编程的基础类.本篇博客就来介绍下Thread类的常用API和常见用法. Thread类常用的方法如下: Thread.active ...

  7. Docker虚拟化之<基础理论>

    1.虚拟化技术的概念 (1)虚拟化技术主要是将物理的资源转变为逻辑上可以管理的资源,以打破物理结构上的壁垒,让计算元件运行在虚拟的基础上,而不是真实的物理资源上.(2)虚拟化技术的底层是要进行虚拟化的 ...

  8. 42步进阶学习—让你成为优秀的Java大数据科学家!

    作者 灯塔大数据 本文转自公众号灯塔大数据(DTbigdata),转载需授权 如果你对各种数据类的科学课题感兴趣,你就来对地方了.本文将给大家介绍让你成为优秀数据科学家的42个步骤.深入掌握数据准备, ...

  9. 把Git Repository建到U盘上去

    Git很火.原因有三: 它是大神Linus Torvalds的作品,天然地具备神二代的气质和品质: 促进了生产力的发展,Git的分布式版本控制理念,并非首创,但非常适合开源社区的协作方式(不存在mas ...

  10. Educational Codeforces Round 34 (Rated for Div. 2) A B C D

    Educational Codeforces Round 34 (Rated for Div. 2) A Hungry Student Problem 题目链接: http://codeforces. ...