黑马程序员技术交流社区

标题: java内存泄露了怎么解决? [打印本页]

作者: 黑马-zhangping    时间: 2012-11-4 11:10
标题: java内存泄露了怎么解决?
java内存泄露了怎么解决?
作者: 朱宏青    时间: 2012-11-4 12:22
这个问题可以说小 也可以说麻烦,首先你要知道是哪个引用出了问题:被留置以后却还有代码在访问,必须修改 让gc回收系统回收.

只要在最后都没有指向的引用,都会被gc回收. 记住这点就好.

所以编程序的时候要千万注意,不要出现无畏的废引用,浪费内存总是不好的.
作者: 金曦    时间: 2012-11-4 14:13
1、尽早释放无用对象的引用。好的办法是使用临时变量的时候,让引用变量在退出活动域后,自动设置为null,暗示垃圾收集器来收集该对象,防止发生内存泄露。
2、我们的程序里不可避免大量使用字符串处理,避免使用String,应大量使用StringBuffer,每一个String对象都得独立占用内存一块区域
3、尽量少用静态变量,因为静态变量是全局的,GC不会回收的;
4、避免集中创建对象尤其是大对象,JVM会突然需要大量内存,这时必然会触发GC优化系统内存环境;
5、尽量运用对象池技术以提高系统性能;生命周期长的对象拥有生命周期短的对象时容易引发内存泄漏,例如大集合对象拥有大数据量的业务对象的时候,可以考虑分块进行处理,然后解决一块释放一块的策略。
6、不要在经常调用的方法中创建对象,尤其是忌讳在循环中创建对象。可以适当的使用hashtable,vector 创建一组对象容器,然后从容器中去取那些对象,而不用每次new之后又丢弃
7、一般都是发生在开启大型文件或跟数据库一次拿了太多的数据,造成 Out Of Memory Error 的状况,这时就大概要计算一下数据量的最大值是多少,并且设定所需最小及最大的内存空间值

作者: 刘丽娜    时间: 2012-11-4 15:09
一旦知道确实发生了内存泄漏,就需要更专业的工具来查明为什么会发生泄漏.JVM自己是不会告诉您的.这些专业工具从JVM获得内存系统信息的方法基本上有两种:JVMTI和字节码技术(byte code instrumentation).Java虚拟机工具接口(Java Virtual Machine Tools Interface,JVMTI)及其前身Java虚拟机监视程序接口(Java Virtual Machine Profiling Interface,JVMPI)是外部工具与JVM通信并从JVM收集信息的标准化接口.字节码技术是指使用探测器处理字节码以获得工具所需的信息的技术.

Optimizeit是Borland公司的产品,主要用于协助对软件系统进行代码优化和故障诊断,其中的Optimizeit Profiler主要用于内存泄漏的分析.Profiler的堆视图就是用来观察系统运行使用的内存大小和各个类的实例分配的个数的.

首先,Profiler会进行趋势分析,找出是哪个类的对象在泄漏.系统运行长时间后可以得到四个内存快照.对这四个内存快照进行综合分析,如果每一次快照的内存使用都比上一次有增长,可以认定系统存在内存泄漏,找出在四个快照中实例个数都保持增长的类,这些类可以初步被认定为存在泄漏.通过数据收集和初步分析,可以得出初步结论:系统是否存在内存泄漏和哪些对象存在泄漏(被泄漏).

接下来,看看有哪些其他的类与泄漏的类的对象相关联.前面已经谈到Java中的内存泄漏就是无用的对象保持,简单地说就是因为编码的错误导致了一条本来不应该存在的引用链的存在(从而导致了被引用的对象无法释放),因此内存泄漏分析的任务就是找出这条多余的引用链,并找到其形成的原因.查看对象分配到哪里是很有用的.同时只知道它们如何与其他对象相关联(即哪些对象引用了它们)是不够的,关于它们在何处创建的信息也很有用.
  
最后,进一步研究单个对象,看看它们是如何互相关联的.借助于Profiler工具,应用程序中的代码可以在分配时进行动态添加,以创建堆栈跟踪.也有可以对系统中所有对象分配进行动态的堆栈跟踪.这些堆栈跟踪可以在工具中进行累积和分析.对每个被泄漏的实例对象,必然存在一条从某个牵引对象出发到达该对象的引用链.处于堆栈空间的牵引对象在被从栈中弹出后就失去其牵引的能力,变为非牵引对象.因此,在长时间的运行后,被泄露的对象基本上都是被作为类的静态变量的牵引对象牵引.





欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2