`

java虚拟机学习笔记之垃圾收集(上)

阅读更多

java程序是运行在java虚拟机当中的,在java虚拟机的堆中运行着程序所创建的对象。可以使用new,newarray,anewarray,multianewarray指令来创建对象,但是没有明确的代码来释放这些对象所使用的空间。垃圾收集就是自动释放不在被程序使用的对象的过程。为了能够无限制的使用内存,大部分的java虚拟机都附带有垃圾收集堆。

★为什么使用使用垃圾收集

垃圾收集,也就是把程序中不需要的对象作为“垃圾”进行回收,以精确,新鲜的说法就是“内存回收”。当一个对象不再被程序引用的时候,所使用的堆空间可以被回收,以便后续创建的新的对象使用。垃圾收集器必须能断定哪些对象是不再被引用的,并且能够把它们所占据的堆空间释放出来。在释放不再被引用的对象的过程中,垃圾收集器运行将要被释放对象的终结方法----finalizer

除此之外,垃圾收集器还要处理堆碎块。堆碎块是在正常的程序运行过程中产生的。新的对象分配了空间,不再被引用的对象被释放,所以堆内存的空闲位置介于活动对象之间。请求分配新对象时可能不得不增大堆空间放得下新的对象。在一个虚拟的内存系统中,增长堆所需要的额外空间会影响运行程序的性能。在内存较小的嵌入式系统中,碎块导致虚拟机产生不必要的“内存不足”错误。

将以上这种工作交给java虚拟机有几个好处:

1.可以提高生产效率。在一个不具有垃圾收集机制的语言下编程,可能要花很多的时间来解决难以捉摸的内存问题。使用java,恰恰可以充分的,有效的利用这些时间。

2.可以保持程序的完整性。垃圾收集是java安全策略的一个重要的部分。

存在的缺陷:

加大了程序的负担,可能影响程序的性能。java虚拟机必须追踪哪些对象被正在执行的程序所使用,并且动态的终结释放不再被使用的对象。和明确释放不再被使用的内存比起来,这个活动需要更多的CPU时间。并且,在垃圾收集环境下,程序员对安排CPU时间来释放无用的对象缺乏控制。

★垃圾收集算法

任何垃圾收集算法必须做的两件事情:

1.必须检测出垃圾对象

2.必须回收垃圾对象所使用的堆空间并还给程序

垃圾检测通常建立一个根对象的集合并且检查从这些根对象开始的可触及性来实现。如果正在执行的程序可以访问到的根对象和某个对象之间存在引用路径,这个对象就是可触及的。对于程序来说,根对象总是可以访问的。从这些根对象开始,任何可以被触及的对象都被认为是“活动”的对象。无法触及的对象被认为是垃圾,因为它们不再影响程序的未来执行。

根对象来源:

1.包含局部变量中的对象引用和栈帧的操作数栈。

2.被加载的类的常量池中的对象引用,比如字符串

3.潜在的来源,java虚拟机运行时数据区中从垃圾收集器的堆中分配的部分。

区分活动的对象和垃圾的两个基本方法是引用计数和跟踪。引用计数垃圾收集器通过为堆中的每个对象保存一个计数来区分活动对象和垃圾对象。这个计数记录下了对那个对象的引用的次数。跟踪垃圾收集器实际上追踪从根节点开始的引用图。在追踪中遇上的对象以某种方式打上标记,当追踪结束时,没有被打上标记的对象就被判定是不可触及的,可以被当做垃圾收集。

在编程中寻找快乐,在快乐中自由编程!!!

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics