Java的垃圾回收机制问题

---------------------- ASP.Net+Android+IOS开发.Net培训、期待与您交流! ----------------------
1.首先要明确两个概念,内存泄露(memory leak) 和 内存溢出(out of memory)
memory leak,程序创建对象分配空间使用后,没有释放相应的内存,多次循环后导致可用物理内存减少。
out of memory, 程序申请的内存大小超出了系统所能提供的内存大小。

内存泄露会导致内存溢出!

2.然后讲一讲垃圾回收机制(GC--garbage collection)
GC将自动回收本系统认为是垃圾的内存空间(堆空间)。

他的特点是:

1.垃圾收集是一种从无用对象收其所占用的内存,并使回收的内存能被再次使用的机制。 
2.无用对象是值它不能被程序中处于活动状态的部分引用(个人理解就是没有引用指向该对象时)。
3.垃圾回收机制(gc)处于低优先级的线程内,当使用内存较少时运行,但不能保证何时运行 
4.不可能强制运行垃圾回收线程,但是调用语句System.gc()有可能激活垃圾收集程序。 
5.在垃圾回收机制中无法保证对象被垃圾回收的顺序,也无法保证finalize()的方法被调用的顺序。
6.环形引用并不能阻止对象被回收

java中创建一个对象需要:在栈中创建一个引用变量,在堆中创建对象,引用变量指向对象。
当GC被调用时,他将按照栈中开始跟踪当发现没有被引用的空间时就释放。

一般来说内存泄漏有两种情况。一种情况如在C/C++语言中的,在堆中的分配的内存,在没有将其释放掉的时候,就将所有能访问这块内存的方式都删掉(如指针重新赋值);另一种情况则是在内存对象明明已经不需要的时候,还仍然保留着这块内存和它的访问方式(引用)。第一种情况,在Java中已经由于垃圾回收机制的引入,得到了很好的解决。所以,Java中的内存泄漏,主要指的是第二种情况。
下面举个小例子~

 Vector v=new Vector(10);
 for (int i=1;i<100; i++){
 Object o=new Object();
 v.add(o);
 o=null;
 }

该例子中引用变量o的值被手动赋值为null,也就是说coder主观上要释放其指向对象所站的空间。但事实上呢,当GC顺着栈查过来时,发现该内存在v引用变量所引用的内存中被引用了(链式引用)。。GC就放过了这块内存,于是乎内存泄露就产生了。

再举个更实际的例子:

public class FileSearch{
 
     private byte[] content;
     private File mFile;
     
     public FileSearch(File file){
         mFile = file;
     }
 
     public boolean hasString(String str){
         int size = getFileSize(mFile);
         content = new byte[size];
         loadFile(mFile, content);
         
         String s = new String(content);
         return s.contains(str);
     }
 }

FileSearch类中有一个函数hasString,用来判断文档中是否含有指定的字符串,coder的本意是,根据文件名新建一个FileSearch对象,然后调用hasString方法,传入要查找的字符串,然后返回。
实际上呢,当调用hasString方法后,整片文章被导入到  成员变量content数组,由于content不是函数局部变量,在函数调完后并没有释放栈中的content引用变量,于是乎 就泄了(我指的是内存。。囧),当有人用该类编写的代码时,也没有释放FileSearch引用的话,多查几次之后就会拖慢整个系统。。。

很明显,这样的内存泄露都来自于代码逻辑层面,有良好的编码风格,考虑好变量的生命周期,那么会减少内存泄露产生的可能。

---------------------- ASP.Net+Android+IOS开发.Net培训、期待与您交流! ----------------------

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Java垃圾回收机制Java语言的一项重要特性,它可以自动管理内存,减轻了程序员手动释放内存的负担。Java垃圾回收机制主要通过垃圾收集器(Garbage Collector)来实现。 在Java中,当一个对象不再被引用时,就可以被判定为垃圾垃圾收集器会定期扫描堆内存,找出不再被引用的对象,并将其回收释放内存空间。这样,程序员就不需要手动释放对象所占用的内存,大大简化了内存管理的工作。 Java垃圾回收机制基于以下两个核心概念: 1. 引用计数法:每个对象都有一个引用计数器,当有新的引用指向该对象时,计数器加1;当引用失效时,计数器减1。当计数器为0时,表示该对象不再被引用,可以被回收。但是,引用计数法无法解决循环引用的问题,即两个或多个对象相互引用,但与程序的根节点没有直接引用关系,导致无法被回收。 2. 可达性分析算法:Java垃圾回收机制采用可达性分析算法来判断对象是否可被回收。该算法从程序的根节点(如静态变量、方法参数等)出发,通过引用链追踪对象的引用关系,如果一个对象不可达(即无法通过引用链与根节点相连),则被判定为垃圾,可以被回收Java垃圾回收机制具有以下优点: 1. 简化了内存管理,减少了内存泄漏和野指针等问题的发生。 2. 提高了程序的可靠性和稳定性,减少了因为内存管理错误导致的程序崩溃。 3. 提高了开发效率,程序员不需要手动释放内存,可以更专注于业务逻辑的实现。 然而,垃圾回收机制也存在一些缺点: 1. 垃圾回收过程会占用一定的系统资源,可能会导致程序的运行速度变慢。 2. 垃圾回收的时间是不确定的,可能会导致程序在某些时刻出现短暂的停顿。 相关问题: 1. Java垃圾回收机制是如何工作的? 2. 什么是引用计数法?它有什么缺点? 3. 什么是可达性分析算法?它如何判断对象是否可被回收? 4. 垃圾回收机制有哪些优点和缺点?

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值