Java垃圾回收机制

来源:互联网 发布:淘宝店铺添加客服 编辑:程序博客网 时间:2024/05/21 14:00

1. 问题一:Java 垃圾回收机制 如何判断一个对象是否die?

JVM管理的堆中内存,几乎存放存放所有的对象实例,如果一个对象在程序中没有任何引用指向他,那么该内存对象可以被收回,因此将 没有任何引用指向此对象 说明这个对象是Die,是可以被回收的对象。Java中通过引用与对象进行关联,操作对象必须对此对象进行引用,一种最简单的办法通过引用计算的方法判断对象是否被回收,但是这种方法无法解决循环引用的问题。

垃圾回收器:回收的是无任何引用的对象占用的空间不是这个对象 。回收老的空间给新的对象进行使用。JVM通过。

System.gc()  /  Runtime.getRuntime().gc() 显示的通知JVM进行一次垃圾回收。事实真正的垃圾回收时间不可预料的,主要和线程抢占有关系。

注意:System.gc() 并不能JVM立即做出垃圾回收反应只是让垃圾回收能够更加的容易提前发生

2. 垃圾回收算法:

  • 引用计数算法(利用对象中引用计算器--无法解决循环引用)
  • Tracing 回收(利用JVM维护对象的引用图,遍历有向图没有被标记的图像就可以被回收)
  • 压缩回收算法(带来性能损伤)
  • 复制回收算法(堆内存分为两块相同区域,任何时刻只有一个内存块被使用,内存耗尽将对象 紧凑复制到另外一块内存中 消除堆碎片但是增大的内存空间)
  • 按代价回收(大部分对象短暂的生命周期,较小对象较长生命周期 ,将经过多次收集存活的对象转移到高一级堆中,减小扫描次数)
3.finalize()方法作用处理通过其他方式(C++ malloc 函数)开辟内存空间 或者垃圾回收器无法处理的对象
      通知回收器不能处理特性对象在回收之前进行资源的释放,特性对象 打开的文件资源或者通过调用C++中malloc函数分配的空间没有调用free函数释放。
调用finalize函数的对象只有在下一次的垃圾回收的动作时候才会真正释放回收,本次不会

  

二. Java的GC堆中垃圾引用垃圾回收机制,自动进行垃圾回收 为什么Java中还是存在内存泄漏问题?

Java中内存空间是否被回收两个标准: ① 对象赋予NULL,之后没有被使用过 ②对象赋予新值重新分配了内存。 内存泄漏有两种情形:堆中申请new的内存没有被释放(Java垃圾回收机制)②不在使用对象还有内存 这样垃圾回收机制无法保证对象被释放。经典实例:不断循环创建对象加入到Vector容器中 如下图:

Vector v=new Vector();for(int i=0;i<10;i++){       Object o=new Object();        v.add(o);}
退出循环o作用域over 但是v使用这些对象 导致垃圾回收器无法回收o对象。


Java语言中 内存泄漏问题很多:主要以下方面:

 1).静态的集合类:HashMap和Vector静态的容器,生命周期与程序一样长,那么其中不使用对象不会释放

         不使用集合之后将其进行 clear

 2)各种动态链接 数据库连接,网络连接和IO连接,显示的进行连接的关闭

3). 监听器

4).变量不合理作用域:定义范围大于其使用范围+没有及时将对象设置null 不使用对象没有设置成null

5).单例模式可能引起内存释放。