内存泄露
所谓内存泄露就是指一个不再被程序使用的对象或变量一直被占据在内存中。
java中有垃圾回收机制,它可以保证一对象不再被引用的时候,即对象编程了孤儿的时候,对象将自动被垃圾回收器从内存中清除掉。由于Java 使用有向图的方式进行垃圾回收管理,可以消除引用循环的问题,例如有两个对象,相互引用,只要它们和根进程不可达的,那么GC也是可以回收它们的,例如下面的代码可以看到这种情况的内存回收:
public class GarbageTest {
public static void main(String[] args) throws IOException {
try {
gcTest();
} catch (IOException e) {
e.printStackTrace();
}
System.out.println("has exited gcTest!");
System.in.read();
System.in.read();
System.out.println("out begin gc!");
for(int i=0;i<100;i++)
{
System.gc();
System.in.read();
System.in.read();
}
}
private static void gcTest() throws IOException {
System.in.read();
System.in.read();
Person p1 = new Person();
System.in.read();
System.in.read();
Person p2 = new Person();
p1.setMate(p2); //p1中包含p2的引用
p2.setMate(p1); //p2中包含p1的引用
System.out.println("before exit gctest!");
System.in.read();
System.in.read();
System.gc();
System.out.println("exit gctest!");
}
private static class Person
{
byte[] data = new byte[20000000];
Person mate = null;
public void setMate(Person other)
{
mate = other;
}
}
}
当gcTest()方法运行完毕以后,p1和p2对象都变成了垃圾,他们都不会被根对象所找到。关于根对象请参见《JVM垃圾回收机制总结(2) :基本算法概述
》中的关于“垃圾回收从哪里开始”的讨论。
Java的内存泄露
虽然Java的垃圾回收机制较大程度的降低了内存泄露的可能性,但Java程序员仍然可能会写出发生内存泄露的代码。其原因就是一个已经不被使用的短寿命对象被一个长寿命对象(如类的静态成员对象)引用,这就使得本来要被回收的短寿命对象永远无法被回收,造成内存泄露。
内存泄露的典型情况
(1) 数据结构造成的短暂内存泄露问题,看下面的代码
public class Stack{
private Object[] element=new Object[10];
private int size=0;
public void push(Object ele){
ensureCapacity();
element[size++]=ele;
}
public Object pop(){
if(size==0) throw new EmptyStackException();
return element[--size]; //短暂造成内存泄露
}
private void ensureCapacity(){
if(element.length==size){
Object[] oldElement=element;
element=new Object[size*2+1];
System.arraycopy(oldElement,0,element,0,size);
}
}
}
上面的代码每一次pop()的时候,Stack都会弹出一个元素,在没有加入新元素之前,实际上仍然有一个引用element[x]指向了这个已经弹出的对象,因此GC是不会对其进行垃圾回收的。只有push()新元素的时候使得element[x]=newObject,才会使得以前创建的对象有可能被回收。应该把上面的pop()方法改成下面的代码就安全多了:
public Object pop(){
if(element.length==size) throws EmptyStackException();
Object o=element[--size];
elements[size]=null; //使得GC有机会回收这个对象
return o;
}
分享到:
相关推荐
4. "java内存泄露专题研究和应用_石麟.docx"可能提供了更深入的研究和实际案例,包括如何识别特定类型的内存泄漏,以及针对不同场景下的解决方案。而"ha450.jar"可能是一个示例应用或者工具,用于演示内存泄漏问题...
Java内存泄漏问题是一个重要的主题,尤其对于大型的J2EE应用程序而言,理解并避免内存泄漏至关重要。虽然Java的垃圾收集机制能自动管理内存,但并不意味着程序员可以完全忽视内存管理。以下是一些关于Java内存泄漏的...
这篇博客“JAVA内存泄漏问题处理方法经验总结”分享了作者在处理此类问题时的一些实用技巧和经验,结合源码分析和工具使用,对于Java开发者来说是非常有价值的。 首先,了解内存泄漏的基本概念是至关重要的。内存...
### 关于Java内存泄露问题解决 #### 引言:Java内存管理的核心——垃圾回收机制(GC) Java作为当今产业界和学术界最炙手可热的编程语言之一,以其独特的安全性和可移植性赢得了广泛的应用,尤其是在服务器端编程...
### 如何解决Java内存泄漏 #### 1. 背景 Java凭借其垃圾回收机制大大简化了内存管理,使得开发者无需手动管理内存的释放,从而提升了开发效率。然而,这种自动化管理也可能成为一把双刃剑,特别是当开发人员忽视...
本文将详细介绍如何解决Java内存泄漏问题,帮助开发者更好地理解和应对这一挑战。 #### 二、Java内存模型与内存区域 Java虚拟机(JVM)管理着多种不同类型的内存区域,包括堆内存(Heap Memory)、方法区(Method Area)...
本文将深入探讨如何检测和分析Java内存泄露与溢出,并介绍一种常用的工具——Memory Analyzer(MAT)。 首先,理解内存泄露的概念至关重要。在Java中,内存泄露通常发生在对象不再被程序使用但仍然保持在内存中,...
Java内存泄露是Java开发中常见的一种问题,发生内存泄露可能会导致Java应用程序崩溃或性能下降。在Java中,内存泄露的原因非常多样,例如,静态变量、循环引用、数据库连接池、Session溢出等等。为了检测和解决Java...
总结来说,Java内存泄漏的分析工具如JVisualVM、MAT、JProfiler和Arthas等,提供了丰富的功能来帮助开发者定位和解决内存泄漏问题。理解这些工具的使用方法和特性,结合实际的项目经验,可以有效地防止和修复内存...
【Java内存泄漏问题相关总结】 在Java编程中,内存泄漏是一个严重的问题,它指的是程序中已分配的内存没有被正确地释放,导致这部分内存无法被垃圾收集器(GC)回收,长时间积累会消耗大量系统资源,影响应用性能。...
本文将深入讨论Java内存泄漏的解决方法,提供一些工具和技巧,帮助开发者检测和解决内存泄漏问题。 首先,需要了解什么是内存泄漏。在Java中,内存泄漏通常是指不再使用的对象占用的内存无法被垃圾回收器回收。这种...
本文将深入探讨Java内存分析和内存泄露问题。 首先,我们需要了解Java内存模型的基础。Java内存主要分为三个区域:堆(Heap)、栈(Stack)和方法区(Method Area)。堆用于存储对象实例,栈用于存储方法调用及局部...
"JAVA内存泄漏分析工具"正是一款用于解决此类问题的专业工具,它能帮助开发者定位并修复内存相关的问题,如内存泄漏和内存溢出。 内存泄漏是程序在申请内存后,无法释放已申请的内存空间,一次小的内存泄漏可能看似...
Java内存泄漏问题处理方法经验总结 Java内存泄漏问题处理方法经验总结是Java开发中非常重要的一个方面,今天我们将分享关于Java内存泄漏问题处理方法经验总结的知识点。 首先,Java内存泄漏的问题描述是系统在...
Java内存泄露问题是软件开发过程中常见的难题之一。通过对内存管理机制的理解及上述几种常见内存泄露场景的认识,开发者可以更好地预防和解决这类问题。为了进一步提高代码的质量,建议在开发过程中结合单元测试和...
Java内存泄露是一个严重的问题,它可能导致程序性能下降,甚至导致应用程序崩溃。Eclipse Memory Analyzer(MAT)是一款强大的Java内存分析工具,特别适用于检测和解决内存泄露。标题提到的"java内存泄露分析工具 ...
Java内存泄露的示例代码的知识点总结 Java内存泄露是指Java应用程序中由于某些原因导致的内存不能被正确释放,导致JVM ...通过正确释放资源,避免使用ThreadLocal,正确使用ClassLoader,可以避免Java内存泄露问题。