概述java垃圾回收机制

2025-02-03 版权声明 我要投稿

概述java垃圾回收机制(精选3篇)

概述java垃圾回收机制 篇1

java中的内存java虚拟机自己往治理的,java的内存分配分为两个部分,一个是数据堆,一个是栈。

堆是给开发代码使用的,是在JVM启动时创建,程序在运行的时候一般分配数据堆,把局部的临时的变量都放进往,生命周期和进程有关系,在堆中分配的内存由java虚拟机的自动垃圾回收器来治理,堆内存用来存放由new创建的对象和数组。

栈是留给JVM自己用的,用来存放类的信息的,它和堆不同,运行期内GC不会开释空间,当超过变量的作用域后,java会自动开释掉为该变量所分配的内存空间:

 假如程序声明了static的变量,就直接在栈中运行的,进程销毁了,不一定会销毁static变量。

 在函数中定义的基本类型变量和对象的引用变量都在函数的栈内存中分配 java中有垃圾回收机制:System。gc()即垃圾收集机制是指jvm用于开释那些不再使用的对象所占用的内存。java语言并不要求jvm有gc,也没有规定gc如何工作。垃圾收集的目的在于清除不再使用的对象。gc通过确定对象是否被活动对象引用来确定是否收集该对象。

假如你向系统申请分配内存进行使用(new),可是使用完了以后却不回还(delete),结果你申请到的那块内存你自己也不能再访问,该块已分配出来的内存也无法再使用,随着服务器内存的不断消耗,而无法使用的内存越来越多,系统也不能再次将它分配给需要的程序,产生泄露。一直下往,程序也逐渐无内存使用,就会溢出。

堆的上风是可以动态分配内存大小,生存期也不必事先告诉编译器,由于它是在运行时动态分配内存的。缺点就是要在运行时动态分配内存,存取速度较慢。

栈的上风是存取速度比堆要快,缺点是存在栈中的数据大小与生存期必须是确定的,无灵活性。

JAVA垃圾回收原理

在Java虚拟机规范中,提及了如下几种类型的内存空间:

栈内存(Stack):每个线程私有的。

堆内存(Heap):所有线程公用的。

方法区(Method Area):有点像以前常说的“进程代码段”,这里面存放了每个加载类的反射信息、类函数的代码、编译时常量等信息。

原生方法栈(Native Method Stack):主要用于JNI中的原生代码,平时很少涉及。而Java的使用的是堆内存,java堆是一个运行时数据区,类的实例(对象)从中分配空间。Java虚拟机(JVM)的堆中储存着正在运行的应用程序所建立的所有对象,“垃圾回收”也是主要是和堆内存(Heap)有关。

垃圾回收的概念就是JAVA虚拟机(JVM)回收那些不再被引用的对象内存的过程。一般我们以为正在被引用的对象状态为“alive”,而没有被应用或者取不到引用属性的对象状态为“dead”。垃圾回收是一个开释处于”dead”状态的对象的内存的过程。而垃圾回收的规则和算法被动态的作用于应用运行当中,自动回收。

JVM的垃圾回收器采用的是一种分代(generational)回收策略,共分为三个代:

1)Young(年轻代)

年轻代分三个区。一个Eden区,两个Survivor区。大部分对象在Eden区中产生。当Eden区满时,还存活的对象将被复制到Survivor区(两个中的一个),当这个Survivor

区满时,此区的存活对象将被复制到另外一个Survivor区,当这个Survivor往也满了的时候,从第一 个Survivor区复制过来的并且此时还存活的对象,将被复制“年老区(Tenured)”。需要留意,Survivor的两个区是对称的,没先后关 系,所以同一个区中可能同时存在从Eden复制过来 对象,和从前一个Survivor复制过来的对象,而复制到年老区的只有从第一个Survivor往过来的对象。而且,Survivor区总有一个是空的。

2)Tenured(年老代)

年老代存放从年轻代存活的对象。一般来说年老代存放的都是生命期较长的对象。

3)Perm(持久代)

用于存放静态文件,如Java类、方法等。持久代对垃圾回收没有明显影响,但是有些应用可能动态产生或者调用一些class,例如Hibernate等,在这种时候需要设置一个比较大的持久代空间来存放这些运行过程中新增的类。持久代大小通过-XX:MaxPermSize=进行设置。

虚拟内存初始化的时候会把所有对象都分配到 Eden space,并且大部分对象也会在该区域被开释。当进行 minor GC的时候,VM会把剩下的没有开释的对象从Eden space移动到其中一个survivor spaces当中。此外,VM也会把那些长期存活在survivor spaces 里的对象移动到年老代的“tenured” space中。当 tenured generation 被填满后,就会产生Full GC,Full GC会相对比较慢由于回收的内容包括了所有的 live状态的对象。

GC类型

GC有两种类型:Scavenge GC和Full GC。

 Scavenge GC

一般情况下,当新对象产生,并且在Eden申请空间失败时,就好触发Scavenge GC,堆Eden区域进行GC,清除非存活对象,并且把尚且存活的对象移动到Survivor区。然后整理Survivor的两个区。

 Full GC

对整个堆进行整理,包括Young、Tenured和Perm。Full GC比Scavenge GC要慢,因此应该尽可能减少Full GC。有如下原因可能导致Full GC:1)Tenured被写满;2)Perm域被写满 ;3)System。gc()被显示调用。

上一次GC之后Heap的各域分配策略动态变化有较高的频率对年轻的对象(young generation)进行扫描和回收,而对老对象(old generation)的检查回收频率要低很多。这样就不需要每次GC都将内存中所有对象都检查一遍,这种策略有利于实时观察和回收。

一些对象被创建出来只是拥有短暂的生命周期,比如iterators 和本地变量。

另外一些对象被创建是拥有很长的生命周期,比如高持久化对象等。

各代内存回收规则

Eden Space(heap): 内存最初从这个线程池分配给大部分对象。

Survivor Space(heap):用于保存在eden space内存池中经过垃圾回收后没有被回收的对象。Tenured Generation(heap):用于保持已经在 survivor space内存池中存在了一段时间的对象。Permanent Generation(non-heap): 保存虚拟机自己的静态(refective)数据,例如类(class)和(method)对象。Java虚拟机共享这些类数据。这个区域被分割为只读的和只写的。

Code Cache(non-heap):HotSpot Java虚拟机包括一个用于编译和保存本地代码(native code)的内存,叫做“代码缓存区”(code cache)

JVM如何设置虚拟内存

提示:在JVM中假如98%的时间是用于GC且可用的Heap size 不足2%的时候将抛出此异常信息。

提示:Heap Size 最大不要超过可用物理内存的80%,一般的要将-Xms和-Xmx选项设置为相

同,而-Xmn为1/4的-Xmx值。

提示:JVM初始分配的内存由-Xms指定,默认是物理内存的1/64;JVM最大分配的内存由-Xmx指定,默认是物理内存的1/4。

默认空余堆内存小于40%时,JVM就会增大堆直到-Xmx的最大限制;空余堆内存大于70%时,JVM会减少堆直到-Xms的最小限制。因此服务器一般设置-Xms、-Xmx相等以避免在每次GC后调整堆的大小。

提示:假设物理内存无穷大的话,JVM内存的最大值跟操纵系统有很大的关系。

简单的说就32位处理器固然可控内存空间有4GB,但是具体的操纵系统会给一个限制,这个限制一般是2GB-3GB(一般来说Windows系统下为1。5G-2G,Linux系统下为2G-3G),而64bit以上的处理器就不会有限制了

提示:留意:假如Xms超过了Xmx值,或者堆最大值和非堆最大值的总和超过了物理内存或者操纵系统的最大限制都会引起服务器启动不起来。

提示:设置NewSize、MaxNewSize相等,“new”的大小最好不要大于“old”的一半,原因是old区假如不够大会频繁的触发 Full GC,大大降低了性能

JVM使用-XX:PermSize设置非堆内存初始值,默认是物理内存的1/64;

由XX:MaxPermSize设置最大非堆内存的大小,默认是物理内存的1/4。

解决方法:手动设置Heap size

Set JAVA_OPTS=-Xms800m-Xmx800m-XX:PermSize=128M-XX:MaxNewSize=256m-XX:MaxPermSize=256m

内存溢生产生

1、java。lang。OutOfMemoryError: PermGen space

假如web app用了大量的第三方jar或者应用有太多的class文件而恰好MaxPermSize设置较小,超出了也会导致这块内存的占用过多造成溢出,或者服务器热部署时侯不会清理前面加载的环境,只会将context更改为新部署的,非堆存的内容就会越来越多。PermGen space的全称是Permanent Generation space,是指内存的永久保存区域,这块内存主要是被JVM存放Class和Meta信息的,Class在被Loader时就会被放到PermGen space中,它和存放类实例(Instance)的Heap区域不同,GC(Garbage Collection)不会在主程序运行期对PermGen space进行清理,所以假如你的应用中有很CLASS的话,就很可能出现PermGenspace错误,这种错误常见在web服务器对JSP进行pre compile的时候。假如你的WEB APP下都用了大量的第三方jar,其大小超过了jvm默认的大小(4M)那么就会产生此错误信息了。配置方式参见JVM如何设置虚拟内存

2、java。lang。OutOfMemoryError: Javaheap space

JVM调用GC的频度还是很高的,主要两种情况下进行垃圾回收:当应用程序线程空闲;另一个是java内存堆不足时,会不断调用GC,若连续回收都解决不了内存堆不足的题目时,就会报out of memory错误。由于这个异常根据系统运行环境决定,所以无法预期它何时出现。根据GC的机制,程序的运行会引起系统运行环境的变化,增加GC的触发机会。为了避免这些题目,程序的设计和编写就应避免垃圾对象的内存占用和GC的开销。显示调用System。GC()只能建议JVM需要在内存中对垃圾对象进行回收,但不是必须马上回收,一个是并不能解决内存资源耗空的局面,另外也会增加GC的消耗。配置方式参见JVM如何设置虚拟内存堆大小设置

JVM 中最大堆大小有三方面限制:相关操纵系统的数据模型(32-bt还是64-bit)限制;系统的可用虚拟内存限制;系统的可用物理内存限制。32位系统 下,一般限制在1。5G~2G;64位操纵系统对内存无限制。我在Windows Server 2003 系统,3。5G物理内存,JDK5。0下测试,最大可设置为1478m。

设置内容

1。-Xms:初始堆大小

2。-Xmx:最大堆大小

3。-XX:NewSize=n:设置年轻代大小

4。-XX:NewRatio=n:设置年轻代和年老代的比值。如:为3,表示年轻代与年老代比值为1:3,年轻代占整个年轻代年老代和的1/4

5。-XX:SurvivorRatio=n:年轻代中Eden区与两个Survivor区的比值。留意Survivor区有两个。如:3,表示Eden:Survivor=3:2,一个Survivor区占整个年轻代的1/5

6。-XX:MaxPermSize=n:设置持久代大小

典型设置

 java-Xmx3550m-Xms3550m-Xmn2g-Xss128k-Xmx3550m:设置JVM最大可用内存为

3550M。-Xms3550m:设置JVM促使内存为3550m。此值可以设置与-Xmx相同,以避免每次垃圾回收完成后JVM重新分配内存。-Xmn2g:设置年轻代大小为2G。整个堆大小=年轻代大小+年老代大小+持久代大小。持久代一般固定大小为64m,所以增大年轻代后,将会减小年老代大小。此值对系统性能影响较大,Sun官方推荐配置为整个堆的3/8。-Xss128k: 设置每个线程的堆栈大小。JDK5。0以后每个线程堆栈大小为1M,以前每个线程堆栈大小为256K。更具应用的线程所需内存大小进行调整。在相同物理内 存下,减小这个值能产生更多的线程。但是操纵系统对一个进程内的线程数还是有限制的,不能无穷产生,经验值在3000~5000左右。

 java-Xmx3550m-Xms3550m-Xss128k-XX:NewRatio=4-XX:SurvivorRatio=4

-XX:MaxPermSize=16m-XX:MaxTenuringThreshold=0-XX:NewRatio=4:设置年轻代(包括Eden和两个Survivor区)与年老代的比值(除往持久代)。设置为4,则年轻代与年老代所占比值为1:4,年轻代占整个堆栈的1/5。-XX:SurvivorRatio=4:设置年轻代中Eden区与Survivor区的大小比值。设置为4,则两个Survivor区与一个Eden区的比值为2:4,一个Survivor区占整个年轻代的1/6。-XX:MaxPermSize=16m:设置持久代大小为16m。-XX:MaxTenuringThreshold=0:设置垃圾最大年龄。假如设置为0的话,则年轻代对象不经过Survivor区,直接进进年老代。对于年老代比较多的应用,可以进步效率。假如将此值设置为一个较大值,则年轻代对象会在Survivor区进行多次复制,这样可以增加对象再年轻代的存活时间,增加在年轻代即被回收的概论。

调优总结

 年轻代大小选择

1、响应时间优先的应用:尽可能设大,直到接近系统的最低响应时间限制(根据实际情况

选择)。在此种情况下,年轻代收集发生的频率也是最小的。同时,减少到达年老代的对象。

2、吞吐量优先的应用:尽可能的设置大,可能到达Gbit的程度。由于对响应时间没有要求,垃圾收集可以并行进行,一般适合8CPU以上的应用。

 年老代大小选择

1、响应时间优先的应用:年老代使用并发收集器,所以其大小需要小心设置,一般要考虑

并发会话率和会话持续时间等一些参数。假如堆设置小了,可以会造成内存碎片、高回收频率以及应用暂停而使用传统的标记清除方式;假如堆大了,则需要较长的收集时间。最优化的方案,一般需要参考以下数据获得:

1)并发垃圾收集信息

2)持久代并发收集次数

3)传统GC信息

4)花在年轻代和年老代回收上的时间比例

5)减少年轻代和年老代花费的时间,一般会进步应用的效率

2、吞吐量优先的应用:一般吞吐量优先的应用都有一个很大的年轻代和一个较小的年老代。

原因是,这样可以尽可能回收掉大部分短期对象,减少中期的对象,而年老代尽存放长期存活对象。

 较小堆引起的碎片题目

因为年老代的并发收集器使用标记、清除算法,所以不会对堆进行压缩。当收集器回收时,他会把相邻的空间进行合并,这样可以分配给较大的对象。但是,当堆空间较小时,运行一段时间以后,就会出现“碎片”,假如并发收集器找不到足够的空间,那么并发收集器将会停止,然后使用传统的标记、清除方式进行回收。假如出 现“碎片”,可能需要进行如下配置:

1)-XX:+UseCMSCompactAtFullCollection:使用并发收集器时,开启对年老代的压缩。

2)-XX:CMSFullGCsBeforeCompaction=0:上面配置开启的情况下,这里设置多少次Full

GC后,对年老代进行压缩

性能检测工具使用

利用JDK自带的JControl(图形化监测工具)、JMap(类似于win操纵系统中的任务治理器的结果),可以看出哪些个对象实例化次数、以及内存使用情况来进行调优。

通过代码来进步效率,不健壮代码的特征及解决办法

1、尽早开释无用对象的引用。好的办法是使用临时变量的时候,让引用变量在退出活

动域后,自动设置为null,暗示垃圾收集器来收集该对象,防止发生内存泄露。

2、对于仍然有指针指向的实例,jvm就不会回收该资源,由于垃圾回收会将值为null的对象作为垃圾,进步GC回收机制效率;

3、我们的程序里不可避免大量使用字符串处理,避免使用String,应大量使用

StringBuffer,每一个String对象都得独立占用内存一块区域;

String str = “aaa”;

String str2 = “bbb”;

String str3 = str + str2;

假如执行此次之后str,str2以后再不被调用,那它就会被放在内存中等待Java的gc往回收,程序内过多的出现这样的情况就会报上面的那个错误,建议在使用字符串时能使用StringBuffer就不要用String,这样可以省不少开销;

4、尽量少用静态变量,由于静态变量是全局的,GC不会回收的;

5、避免集中创建对象尤其是大对象,JVM会忽然需要大量内存,这时必然会触发GC

优化系统内存环境;显示的声明数组空间,而且申请数目还极大;

6、尽量运用对象池技术以进步系统性能;生命周期长的对象拥有生命周期短的对象时

轻易引发内存泄漏,例如大对象拥有大数据量的业务对象的时候,可以考虑分块进行处理,然后解决一块开释一块的策略;

7、不要在经常调用的方法中创建对象,尤其是忌讳在循环中创建对象。可以适当的使

用hashtable,vector 创建一组对象容器,然后从容器中往取那些对象,而不用每次new之后又丢弃;

8、一般都是发生在开启大型文件或跟数据库一次拿了太多的数据,造成 Out Of

概述java垃圾回收机制 篇2

目前, 随着面向对象编程思想的成熟, 面向对象的编程语言已占据了当前市场的主流。而C++语言和java语言作为面向对象程序语言的两大主力被广大编程技术人员的普遍使用, 这两种语言的相似之处当然是面向对象的种种共性比如:封装性, 继承性, 多态性等等。但是, 就内存的回收利用也就是常说的垃圾回收, 二者处理方式是有区别的。而且有一个潜在的编程陷阱, 往往有些C++程序员刚开始会误把java语言中的finalize () 方法当作C++中的析构函数。本文就有他们二者的异同之处做出剖析。

二、C++和java中的垃圾回收机制

C++程序语言设计的思想是:程序员要动态地管理内存资源, 以对象的形式使用指针, 程序员必须完成对内存的分配、使用和撤销, 语言自身不会提供帮助。这样设计的目的是使其不依赖于自动垃圾回收, 因为垃圾回收将有一个严重的空间和时间开销, 更有可能带来回收系统实现的复杂性和可移植性。此外, C++的一个设计目标是做许多底层工作, 而垃圾回收将使其不适合做这些工作。但垃圾回收机制, 可以简化设计, 消除许多程序底层引发错误的原因。垃圾回收机制能为用户带来极大的方便, 提供更可靠的存储管理模式[1]。

Java语言提供了自动垃圾收集机制, 换句话说, 程序员负责分配内存和使用, 不用的内存由语言自己撤销。Java的垃圾回收机制放在JVM (Java虚拟机) 里, JVM负责所有垃圾回收, 应用程序只需要在使用时申请空间, 而在撤销对象时不需要处理内存的回收问题。

由此可见, 如果设计成统一的自动垃圾回收系统则无法适用于各种不同的使用环境, 两种语言的垃圾回收机制各有其实现的方法。所以二者的选取无所谓好与坏, 应根据实际需要选择就够了。

三、垃圾回收过程

在C + + 语言中, 全部的对象都应该被销毁。 如果“C+ +”程序中在堆栈上创建了一个局部对象, 这个对象的销毁是基于“右花括号”该对象作用域结尾的地方。如果一个对象是用new关键词创建的, 当程序员调用操作符delete时, 将调用相应的析构函数, 如果程序员忘记调用delete运算符, 就永远不会调用析构函数, 这样就出现了内存泄漏的现象, 对象得不到清理, 而且这种缺陷也无法跟踪。因为这个原因, C++的标准库中设计了一种智能指针, 虽然有局限性, 但它可以解决内存泄漏的问题, 智能指针的标准库的定义格式::std::auto_ptr <>, 将指针包装为类, 然后重写反引用 (dereference) 操作符 (operator->*) 和成员选择操作符 (operator ->) , 来模仿指针的行为。其工作原理是:使用new运算符来构造一个对象并分配内存空间, 通过自动调用析构函数来清理这段内存。

相反, Java不允许建立本地对象, 须使用new建立对象, 在Java中, 也没有删除对象的 (delete) 运算符。因为垃圾收集功能会自动删除无用对象占用的内存空间。Java没有析构函数, 主要是因为有垃圾收集装置, 析构函数不能被垃圾收集装置完全代替, 因此, 有一种解决方案就是, 如果想进行除撤销内存之外的清理工作, 就只能调用java的某个方法, 这相当于使用析构函数, 但不方便[2]。

比如, 把C++堆比作房间, 其中的一个个对象都独自占据一个方格的空间。长时间过后, 对象有可能消失, 可是方格空间还需被占用。在java虚拟机中, 堆的体现形式不一样, 就像是传输东西的带子, 在分配新对象时, 它向前移动, 说明分配速度特别快。Java堆“指针”简单地转移到未分配的地方。其效率远远大于C++, 当然, 在实际工作中还一些有别的开销。

在实际工作中, Java堆工作不一定就像一个传送东西的带子。因为这将会导致频繁的内存分页, 所以会显得比实际需要的内存多, 页面调整会大大影响性能。这个解决方案是加个垃圾收集装置。当它工作时, 可以增加空间和使堆中对象有规律的排列, 通过这种方式, 堆栈指针可以非常容易地到达接近传送带的起始位置, 以避免错误页。重新布置垃圾回收装置对象, 实现速度快, 无限存储空间的堆模型。

现在, 很多Java虚拟机使用垃圾处理技术, 此技术是自适应控制技术。如何对找到的有用对象进行处理, 不同的java虚拟机会有不同的结果。有了块, 利用垃圾回收器就可以把对象复制到废弃的块里。每一块与相应的代数记录是否活着, 一般来说, 如果块被引用到其他地方, 将代数增加。垃圾回收器会对处理之后重新分布的块进行整理处理, 它有利于来处理大量的短暂的临时对象。在Java虚拟监控之下, 垃圾收集器将定期进行清理行动。如果所有的对象是非常稳定的, 但垃圾回收器的效率低, 就会切换到“标记-扫描”的模式。Java虚拟机会做“标记-清理”效果, 如果堆空间存在很多碎片[3], 将切换到“停止-复制模式”。 这就是所谓的“自适应”的技术。虚拟机中有很多附加的技术被用来提高速度, 特别是加载机的操作方面的, 叫做“即时” (JustIn-Time) 编译器技术。该技术可以将全部或部分的程序转换为本地机器代码, 从而提高程序运行速度。

四、C++中的析构函数和java中finalize () 方法的比较

4.1 C++中的析构函数。C++语言中利用构造函数和析构函数, 可以很好的自动分配和撤销资源。所以, 在构造函数中需要分配的资源申请完成, 已经分配的资源在析构函数被回收, 只要一个对象的生命周期结束, 资源的配置是自动被删掉。如果在自由存储区, 即“堆”中创建的对象, 而且被一个指针管理, 是必须借助指针的delete表达式显式的调用析构函数进行资源回收。

4.2 Java中的finalize方法。Java的堆是一个运行时数据区, 类的实例 (对象) 从中分配空间。Java虚拟机 (JVM) 的堆中储存着正在运行的应用程序所建立的所有对象, 这些对象通过new等指令建立, 但是它们不需要程序代码来显式地释放。一般来说, 堆的是由垃圾回收来负责的, 尽管JVM规范并不要求特殊的垃圾回收技术, 甚至根本就不需要垃圾回收, 但是由于内存的有限性, JVM在实现的时候都有一个由垃圾回收所管理的堆。垃圾回收是一种动态存储管理技术, 它自动地释放不再被程序引用的对象, 按照特定的垃圾收集算法来实现资源自动回收的功能[4]。在java在进行垃圾回收前, 会调用对象的finalize方法, 但是真正的垃圾回收则是在下一次垃圾回收动作发生时才进行的。finalize () 的实际作用是在垃圾回收器回收垃圾并释放内存前做一些重要的“清理工作”。对于任何给定对象, Java虚拟机最多只调用一次finalize方法。并且调用finalize方法的工作只需要交给JVM进行就可以了, 极少情况下需要手动调用该方法, 一般情况下不会显示地调用它, 因为这样可能会造成二次调用的情况, 当在第二次调用该方法时, 如果试图释放已经释放的内存时, 会抛出异常, “垃圾”回收工作则无法顺利进行。既然如此, 那么JVM会在何时调用finalize方法呢?一般而言, 只要程序没有在濒临内存空间不足的时候, JVM始终不会主动进行垃圾回收, 也就是说, 只有在程序内存快用完的那一刻, JVM才会主动去搜索已经不再使用的“垃圾”, 并及时对其进行清理工作。

4.3 二者的区别。Java finalize () 方法和c++的析构函数非常相似, 都是自动调用。然而, 二者调用时机不同, C++析构函数总是当对象超出范围时调用, 也就是说, C++析构函数的调用时间是一定的, 可以预知。可是, Java终止器只是当对象被破坏时, 该对象的finalize () 方法被调用, 当垃圾回收器准备删掉被对象占用的无用的内存空间, 它首先调用该对象的finalize () 方法, 然后将该对象的内存回收。但是对象什么时候被破坏, 应用程序是不通知的, 在大多数情况下, 在应用程序结束后, 该对象仍没有被销毁。

初识C++的程序员总会认为finalize方法其实就是C++中的析构函数, 但是这不对的, C++中, 调用了析构函数后, 对象一定会被销毁, 而Java中调用了finalize方法, 垃圾却不一定会被回收。因此得出的结论就是:对象可能不被垃圾回收;垃圾回收并不等于“析构”。

五、结语

Java语言和C++语言都是非常优秀的面向对象程序设计语言, 二者由于应用需求不同, 所以在垃圾回收机制上的设计有所区别, 但最终他们都可以实现垃圾回收, 内存再利用, 只是采用的方法不同而已, 只要编程人员弄清了他们的内因和区别, 按需选择, 实现起来就也就不是难事。

参考文献

[1]Bjarne Stroustrup.The Design and Evolution of C++[M].机械工业出版社, 2001.

[2]埃克尔, (Eckel, Bruce) .C++编程思想[M].机械工业出版社, 2002.

[3]埃克尔, (Eckel, Bruce) .Java编程思想[M].机械工业出版社, 2007.

概述java垃圾回收机制 篇3

伴随着经济的高速发展, 中国城市化进程明显加快。城市人口规模扩张和城市居民消费水平攀升的一个直接后果就是城市居民生活垃圾的海量增加。垃圾问题已经成为困扰中国绝大多数城市的恶疾。目前, 解决垃圾问题的手段大致可分为两类:技术革新和行为改变。使用高能效技术往往会带来垃圾数量的短暂下降, 然而经验表明, 这一优势很快就会被日益增长的垃圾总量所抵消。因此, 环境学者们认为解决城市垃圾问题的根本在于居民的行为改变, 而垃圾分类回收则是居民行为改变在这一问题上的重要体现, 直接关系着垃圾减量化实施的效果。

居民作为城市生活垃圾分类回收行为的主体, 在其中起到关键性的作用, 因此国内外学者开始了对居民生活垃圾分类回收行为干预的积极探索。研究表明, 在中国社会群体中, 影响居民生活垃圾分类回收行为的因素是多方面、多层次的。从个体社会属性看, 年龄、性别、收入、受教育程度和家庭构成都会影响其行为。从个体心理层面看, 环保主义价值观、认知、情感、态度、信念、责任感、控制观和敏感度等均会导致不同的行为意向。从个体行为能力看, 环境知识和行为约束决定了其进行环境行为的可行性。从宏观社会环境看, 经济调节制度、社会规范、宣传教育以及奖惩机制均会产生不同的环境行为导向。

本文将居民实际垃圾分类回收行为作为研究对象, 旨在梳理现有关于垃圾分类回收行为的研究, 主要以社会心理学的行为决定模型和管理学中的行为干预模型为核心, 描述居民生活垃圾分类回收行为及其心理决定机制。本文将厘清看似随机的分类回收行为背后复杂的行为决定机制, 并完整呈现扰动原 (干预措施) →环境心理变量→分类回收行为之间的关系路径。

作为一种特定的环境行为, 有关居民生活垃圾分类回收行为的研究往往被纳入环境行为的研究框架。在现有文献中, 环境行为又被称为“生态行为”、“可持续环境行为”或者“负责任的环境行为”, 它是指益于环境, 或对环境损害最小的行为。随着近年来环境问题的加剧, 环境行为成为多学科的研究热点, 其中以心理学和管理学的研究最具代表性。从心理学角度看, 环境行为是环境价值观和环境态度的外在表现形式, 并由这些因素决定。从管理学的角度看, 个体行为是各种因素作用与制约下的最优选择。我们认为这两种理论并不矛盾:行为条件的变化可以直接改变行为结果, 也可能通过对心理因素的干预间接影响行为。下面, 将从这两个角度梳理心理学中环境行为决定的典型模型和管理学提出的环境行为干预的典型策略。

2 环境行为模型

针对个体行为的决定机制, 心理学家们提出了纷繁复杂的模型。从对这些模型的梳理中不难发现, 模型创立者所倾向的价值观决定了行为决定模型的最终形式。环境保护行为可能缘起于个体对个人利益、社会利益和生态系统利益的关切, 这分别构成了环境保护中的利己主义 (egoistic) 、利他主义 (altruistic) 和生物利益价值观。前一种价值观衍生出一系列以计划行为理论为代表的理性选择模型, 而持后两种价值观的学者往往更倾向于以规范激活模型为代表的行为规范模型。

计划行为理论 (Theory of Reasoned/Planned Behavior) 。计划行为理论的最初形式为理性行为理论, 由Fishbein和Ajzen于1975年提出。这一理论具有高度的功利主义色彩, 它假设人们的环境行为选择是趋利避害的结果。通过对行为的正向和负向影响进行评估后, 个体首先形成针对某一环境行为的态度。同时, 个体也会假设性地考虑施行某一行为后将面临的社会赞许或压力, 即社会规范。在权衡个人的环境态度和其感知到的社会规范后, 个体便形成了一定的行为意向, 它直接决定行为。在1980年和1991年, Ajzen和Fishbein又分别两次对理性行为理论进行了修正, 将感知行为控制和环境制约条件分别纳入了模型, 从而形成了最终的计划行为理论。感知行为控制强调个体对于自身施行某一行为能力的估计, 它通过调节行为意向间接影响行为。而外部环境条件直接决定实施行为的可能性, 与行为意向共同直接影响行为。

规范-激活模型 (Norm-Activation Model) 。规范激活模型的基本出发点是:个人的道德自律是亲社会的环境行为的直接原因。Schwartz (1977) 将个体道德规范定义为, 对于实施亲社会的利他行为的强烈道德责任感。规范激活模型有别于计划行为理论, 是因为它强调非功利的个体道德规范在促成环境行为中的基础性作用。这一模型假设个体会因为社会共享的环境利益而放弃个人利益。但是, 这两种看似矛盾的理论之间又互相联系, 因为个体道德规范的形成最终仍归因于认知、情感、社会规范等计划行为理论中的核心要素。对于环境行为而言, 环保意识和环境知识是形成亲环境的道德规范的前提条件, 而环境问题归因是形成这一个人规范的核心机制。当个体将行为与其环境危害关联起来, 触发情感反应, 产生愧疚心理, 这便形成了道义上的自律。而愧疚心理的形成又与社会规范紧密相关, 它往往是个体行为不符于社会规范的产物 (见图2) 。

价值-信念-规范模型 (Value-Belief-Norm Model) 。1999年, Stern、Dietz、Abel、Guagnano和Kalof等学者在规范激励模型基础上, 融入了价值观理论和新环境范式, 创立了价值-信念-规范模型。该模型的基础是从价值观到行为的五要素因果链条。在这一链条中, 行为的决定因素由较为稳定的心理结构要素, 即利他主义的个体价值观开始, 逐步向更具体的心理要素过度, 这包括由NEP度量的环境态度, 对环境问题不利后果的认知和自我责任归因, 以及针对亲环境行为的个体道德规范。价值-信念-规范模型假设, 这一因果链条上的每一个因子都可能直接地影响其随后的所有因子, 进而规制行为。

价值-信念-规范理论强调价值观在环境行为决定中的基础性作用。以西方社会为背景的研究大多探讨基础价值观及根植于西方社会的特定价值观, 如后物质主义价值观和犹太-基督宗教价值观, 对环境行为的影响。在环境行为的研究被引入中国后, 学者们开始思考中国以至亚洲特有的文化和价值体系, 如集体主义价值观和“天人合一”价值观对环境行为的影响。与追求个人价值的西方人不同, 中国人更重视社会期望和社会身份认同, 这使他们更倾向于采取亲社会和亲自然的行为。而中国文化背景的另一特点在于其传统的儒释道思想皆尊崇“道法自然”和“天人合一”的观念, 强调自然独立于人类社会而存在的独立价值以及人与自然的和谐 (Chan, 2001) 。这些研究构成了对环境行为科学的有益补充。

态度-行为-条件模型 (Attitude-Behavior-Condition Model) 。1995年, Guagnano、Stern和Dietz从政策制定的角度提出了较为实用的态度-行为-条件模型 (ABC模型) , 这一模型强调内部心理因素和外部环境因素在环境行为决定过程中同等重要的作用。传统心理学研究倾向于将人视为具有某种社会认知结构的原子式个体, 从而强调如教育和劝说等认知改变手段对于修正行为的作用。而管理学者则倾向于将人视为受外部力量控制的机器化个体, 从而强调税收和规制等外部干预手段对行为的引导。然而, 单一依靠任意一种理论的政策制定都会有失偏颇, 这是因为在行为改变的过程中, 其关键决定因素也会随之变化, 从一个维度转向另一个维度。尽管以往的心理学模型也或多或少的指出外部环境因素对行为的影响, ABC模型则首次将这两类因素-内部心理因素和外部环境因素-平等地置于一个研究框架中, 它认为行为是作为内部动力的态度和作为外部动力的环境条件两相平衡的结果, 如图4所示。ABC模型是从注重心理过程的态度-行为模型向注重外部条件制约的管理学模型的关键过渡 (见图4) 。

这些行为心理模型从不同角度解释了环境行为的成因, 实际上也反映了其背后所秉承的价值取向和价值判断。同时, 在模型的实际应用过程中, 学者们发现不同行为模型对不同行为的解释力是不同的。一般而言, 规范-激活模型和价值-信念-规范模型等以道德规范为基础的模型能够较好地解释低成本的环境行为, 如政治行动, 争取环境公民权, 接受特定环境政策。而计划行为理论则对于高成本的行为具有较好的解释力, 包括汽车使用, 废物处理, 购买节能灯泡, 使用非漂白纸张, 肉类消费。当然, 对于其他一些行为, 如出行模式选择和废物回收利用, 这两类模型都能够提供比较好的解释。

3 居民生活垃圾分类回收行为的干预策略

与心理学模型强调心理要素对环境行为的影响不同, 管理学研究更关注具体、可控的行为干预策略。从20世纪70年代开始, 为了应对垃圾处理、生态退化等各种环境问题, 学者们针对相关的环境行为进行了大量社会干预实验。通过对这些文献的梳理可以发现如下几类针对居民生活垃圾分类回收行为的典型外部干预策略:

(1) 价格干预。价格调节是经济学中最传统也最经典的行为干预手段。根据古典经济学的供需模型, 当价格上升时, 消费者会自发降低消费量, 从而在更低的消费水平上实现市场新的均衡。所以, 很多学者相信, 价格机制可以有效的实现环境行为干预。

(2) 信息反馈。很多研究显示, 个体往往并不在意自己的环境行为, 而信息反馈可以补偿这一意识缺失, 使环境行为在个体意识中变得更为突出。最常见的反馈方式是提示人们其当期的环境行为状况, 并与过往进行对比。而更高级的反馈方式是同时提供关于他人的环境行为情况, 形成社会比照压力。比照信息的提供可以通过多种方式实现, 如提供完整的社区家庭环境行为列表清单, 提供居民自身环境行为评分的排名, 或仅提供社区环境行为评分均值等统计信息。无论是增强环境行为意识, 还是形成社会比照压力, 信息反馈机制都是通过影响个人的心理要素来间接影响行为的。

(3) 环保示范。示范策略的核心是通过各种媒介 (如文字、语音和影像等) 向个体简明扼要地传达环保的相关技巧和知识, 从而改变个体的知识结构和行为能力, 进而促成环境行为。这一策略的基本假设是, 了解环境保护行为的影响和特定环保技巧能够分别增强个体的环保意识和行为控制感, 帮助消除环保行为的障碍。这实际上是一种环境教育策略。

(4) 奖励惩罚。作为一种经济激励手段, 奖惩措施与价格手段有相似的干预结构。无论是奖励环保行为, 还是惩罚破坏环境的行为, 这都相当于增加了环境行为的机会成本。同时, 奖惩措施的实施一般都需要设定某一用能标准值 (目标值) , 当垃圾分类回收量低于这一目标时实施惩罚, 当回收量高于这一目标时实施奖励, 或者二者兼而有之。从这个意义上讲, 奖惩措施又具有了目标设定策略的性质。实验结果表明, 无论是自我设置的目标还是外部施加的目标都可以影响行为, 其有效性取决于目标设置的难易程度。一般而言, 设定相对困难的目标会带来行为的显著改变, 而易于完成的目标则不会。

与心理模型对不同环境行为的解释力差异相似, 不同的干预措施也会对不同的生活垃圾分类回收行为和不同社会经济背景的居民产生不同效果。而且, 干预手段的有效性还取决于其作用的程度、频率、时长等因素。由于大多数干预措施都是暂时的, 所以有必要在未来的研究中考虑干预措施的长期效应。另外, 大多数关于垃圾分类回收行为干预措施的研究都偏重于干预手段-节能行为之间的关联, 而忽略了干预手段的作用机制, 如外部干预是如何改变个体的心理因素从而改变行为的。这些都有待于更深入的研究。

4 结论

通过改变人们的行为习惯来加强个人的环境行为, 这样的研究在西方由来已久。学者们不仅关注什么样的干预手段可以有效地促进垃圾分类回收行为, 更关心这样的行为改变是通过什么心理渠道完成的。那么, 通过改变居民的行为模式来实现生活垃圾分类回收的策略是否可行呢?管理学, 心理学和环境科学领域的学者都给出了肯定的答案。学者们试图寻找有效的干预措施来促成垃圾分类回收, 这些措施包括:劝说 (activator) 、示范 (demonstration) 、承诺 (commitment) 、信息反馈 (feedback) 、奖励 (reward) 和惩罚 (penalty) 等。它们通过改变人们的环境预期, 强化人们的环保知识, 解决分类回收处理中的信息不对称, 进而改变人们的垃圾处理行为。虽然作用机理不近相同, 但实验结果表明, 大部分干预措施都实现了垃圾分类回收行为的改变。

在环境保护、促进可持续发展已经成为国家议题的当代, 我们应当给予居民生活垃圾分类回收行为足够的重视, 并寻找相应的渠道探索促成垃圾分类回收处理的有效方式和机制。这不仅有利于资源的可持续利用, 更可以通过长期行为的调节带来中国民众垃圾分类回收心理的改变, 从而完成向环境友好型社会的转变。

参考文献

[1]Ajzen, I, &Fishbein, M.Understanding Attitudes and Predicting Social Behavior.New Jersey:Prentice-Hall, 1980.

[2]Ajzen, I.The theory of planned behavior.Organizational Behavior Human Decision Process, 1991, 50, 179~211.

[3]Alcott, H.Social norms and energy conservation.Journal of Public Economics, 2011, 95 (9~10) :1082~1095.

[4]Attari, S.Z., De Kay, M.L., Davidson, C.I., &Bruine de Bruin, W.Public perceptions of energy consumption and savings.Proceedings of the National Academy of Sciences, 2010, 107 (37) :16054~16059.

[4]Schultz, P.W., Nolan, J.M., Cialdini, R.B., Goldstein, N.J.&Griskevicius, V.The constructive, destructive, and reconstructive power of social norms.Psychological Science, 2007, 18 (5) :429~434.

[5]Sexton, R.J., Brown Johnson, N., &Konakayama, A..Consumer response to continuous-display electricity-use monitors in a time-of use pricing experiment.Journal of Consumer Research, 1987, 14:55~62.

[6]马诗院, 马建华.我国城市生活垃圾分类收集现状及对策.环境卫生工程, 2007.

[7]刘宇伟.消费者家庭节能行为的综合模型.社会科学战线, 2009, 12:56~62.

[8]曲英.城市居民生活垃圾源头分类行为的理论模型构建研究.生态经济, 2009:135~141.

上一篇:精准扶贫捐赠感谢信下一篇:生产车间员工述职报告2022年