Java的垃圾回收机制问题
2014-01-17 11:44
309 查看
----------------------
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中的内存泄漏,主要指的是第二种情况。
下面举个小例子~
该例子中引用变量o的值被手动赋值为null,也就是说coder主观上要释放其指向对象所站的空间。但事实上呢,当GC顺着栈查过来时,发现该内存在v引用变量所引用的内存中被引用了(链式引用)。。GC就放过了这块内存,于是乎内存泄露就产生了。
再举个更实际的例子:
FileSearch类中有一个函数hasString,用来判断文档中是否含有指定的字符串,coder的本意是,根据文件名新建一个FileSearch对象,然后调用hasString方法,传入要查找的字符串,然后返回。
实际上呢,当调用hasString方法后,整片文章被导入到 成员变量content数组,由于content不是函数局部变量,在函数调完后并没有释放栈中的content引用变量,于是乎 就泄了(我指的是内存。。囧),当有人用该类编写的代码时,也没有释放FileSearch引用的话,多查几次之后就会拖慢整个系统。。。
很明显,这样的内存泄露都来自于代码逻辑层面,有良好的编码风格,考虑好变量的生命周期,那么会减少内存泄露产生的可能。
----------------------
ASP.Net+Android+IOS开发、.Net培训、期待与您交流! ----------------------
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培训、期待与您交流! ----------------------
相关文章推荐
- 怎么在面试时回答java垃圾回收机制相关问题?
- Java垃圾回收机制与内存泄露问题
- 怎么在面试时回答Java垃圾回收机制(GC)相关问题?
- java垃圾回收机制---面试的问题
- JAVA垃圾回收机制与内存泄露问题
- JAVA垃圾回收机制与内存泄露问题
- JAVA垃圾回收机制与内存泄露问题
- tomcat java.lang.OutOfMemoryError: Java heap space 问题解决;Java垃圾回收机制详解和调优相关链接
- 内部类(成员、静态、方法)| java帮助文档 | 垃圾回收机制
- 全面分析Java的垃圾回收机制
- java学习笔记4_垃圾回收机制
- 成为JavaGC专家Part I — 深入浅出Java垃圾回收机制
- Java垃圾回收机制
- 浅析Java垃圾回收机制
- java垃圾回收机制
- Java的垃圾回收机制
- Java垃圾回收机制2
- Java的垃圾回收机制
- Java垃圾回收机制
- java垃圾回收机制学习