Java内存泄露情况
JVM回收算法 是很复杂的,我也不知道他们怎么实现的,但是我只知道他们要实现的就是:对于没有被引用的对象是可以回收的。所以你要造成内存泄露就要做到:
持有对无用对象的引用!
不要以为这个很轻易做到,既然无用,你怎么还会持有它的引用? 既然你还持有它,它怎么会是无用的呢?
以下以堆栈更经典这个经典的例子来剖析。
Java代码
public class Stack {
private Object[] elements=new Object[10];
private int size = 0;
public void push(Object e){
ensureCapacity();
elements[size++] = e;
}
public Object pop(){
if( size == 0)
throw new EmptyStackException();
return elements[--size];
}
private void ensureCapacity(){
if(elements.length == size){
Object[] oldElements = elements;
elements = new Object[2 * elements.length+1];
System.arraycopy(oldElements,0, elements, 0, size);
}
}
}
上面的原理应该很简单,假如堆栈加了10个元素,然后全部弹出来,虽然堆栈是空的,没有我们要的东西,但是这是个对象是无法回收的,这个才符合了内存泄露的两个条件:无用,无法回收。
但是就是存在这样的东西也不一定会导致什么样的后果,假如这个堆栈用的比较少,也就浪费了几个K内存而已,反正我们的内存都上G了,哪里会有什么影响,再说这个东西很快就会被回收的,有什么关系。下面看两个例子。
例子1
Java代码
public class Bad{
public static Stack s=Stack();
static{
s.push(new Object());
s.pop(); //这里有一个对象发生内存泄露
s.push(new Object()); //上面的对象可以被回收了,等于是自愈了
}
}
因为是static,就一直存在到程序退出,但是我们也可以看到它有自愈功能 ,就是说假如你的Stack最多有100个对象,那么最多也就只有100个对象无法被回收其实这个应该很轻易理解,Stack内部持有100个引用,最坏的情况就是他们都是无用的,因为我们一旦放新的进取,以前的引用自然消失!
例子2
Java代码
public class NotTooBad{
public void doSomething(){
Stack s=new Stack();
s.push(new Object());
//other code
s.pop();//这里同样导致对象无法回收,内存泄露.
}//退出方法,s自动无效,s可以被回收,Stack内部的引用自然没了,所以
//这里也可以自愈,而且可以说这个方法不存在内存泄露问题,不过是晚一点
//交给GC而已,因为它是封闭的,对外不开放,可以说上面的代码99.9999%的
//情况是不会造成任何影响的,当然你写这样的代码不会有什么坏的影响,但是
//绝对可以说是垃圾代码!没有矛盾吧,我在里面加一个空的for循环也不会有
//什么太大的影响吧,你会这么做吗?
}
分享到:
相关推荐
以下我们将深入探讨如何在Java中编写可能导致内存泄露的代码,以及如何避免这种情况。 1. **强引用:**在Java中,对象间的引用分为强引用、软引用、弱引用和虚引用四种。最常见的内存泄露就是由于过度使用强引用...
5. **静态分析**:使用静态代码分析工具,如Coverity、PVS-Studio等,它们可以在编译阶段检查代码,发现可能导致内存泄漏的模式。 代码示例通常会展示如何自定义分配器,记录分配信息,或者如何使用智能指针来防止...
当存在多个指针指向同一块内存时,错误的释放顺序也会导致内存泄露。例如,先释放了某个指针指向的内存,之后又尝试通过另一个指向这块内存的指针来访问它。 ##### 3. 单例模式下的内存泄露 在单例模式下,如果对象...
内存泄漏指的是程序在分配了内存后未能正确释放,导致这部分内存无法再被程序使用,随着时间推移,大量的内存泄漏可能会耗尽系统资源,严重影响程序性能甚至导致系统崩溃。因此,理解和掌握如何检测和防止内存泄漏...
标题中的“一个PHPUnit插件可以检测经过测试的代码或测试中的内存泄漏”指的是在PHP开发过程中,使用PHPUnit作为测试框架时,有一款插件能够帮助开发者检测被测试代码或者测试用例自身是否存在内存泄漏问题。内存...
对于VC++开发人员来说,理解并掌握内存泄漏检查的方法对于编写高效、稳定的代码至关重要。 描述中的"看代码就知道怎么使用了"意味着这个压缩包可能包含一个简单的示例程序,展示了如何在VC++项目中集成内存泄漏检查...
- 避免全局变量和静态变量,它们可能导致内存泄漏更难以追踪。 - 在分配内存后立即初始化,确保在不再需要时及时释放。 - 使用内存池来管理小块内存,减少碎片和泄漏的可能性。 - 对于复杂的内存管理场景,考虑使用...
总之,内存泄漏检测工具是程序员的得力助手,它们可以帮助我们编写更健壮、更高效的代码。cppcheck作为其中的一员,以其高效、易用的特点深受开发者喜爱。掌握并利用好这类工具,无疑能大大提高我们的编程质量和效率...
在实际使用中,开发者可以启动该工具,然后进行常规操作或执行可能导致内存泄漏的代码段。当程序执行完毕后,工具会将检测到的内存泄漏情况以文本文件的形式保存在设备的Flash上。这份报告包含了内存泄漏的时间、...
- **难以定位**:内存泄漏的问题通常较为隐蔽,只有当程序运行一段时间后才会显现出来,而且通常只能通过获取程序源代码进行深入分析才能发现。 #### 四、内存泄漏的分类 - **堆内存泄漏**:这是最常见的内存泄漏...
内存泄漏是指程序在申请内存后,无法释放已申请的内存空间,一次小的内存泄漏可能看似无害,但随着时间推移,累积的内存泄漏会导致系统资源耗尽,从而影响程序性能,甚至导致程序崩溃。因此,了解和掌握检测内存泄漏...
在C/C++编程中,内存泄漏是一个常见的问题,它会导致程序效率下降,甚至崩溃。为了解决这个问题,程序员可以利用一些内存泄漏检测工具。本文将详细介绍几款实用的C/C++内存泄漏检测工具,帮助程序员有效地找出并修复...
未正确回收的内存可能导致内存泄漏,随着时间的推移,这可能会耗尽可用内存,影响系统的性能和稳定性。 5. **内存碎片**:内存碎片是内存管理中的一个常见问题,分为内部碎片和外部碎片。内部碎片是分配给一个进程...
由于C++不提供自动垃圾回收机制,程序员需要手动分配和释放内存,这既赋予了我们高度的灵活性,也带来了潜在的内存泄漏风险。下面将详细讨论C++内存管理中的关键知识点,以及如何防止内存泄漏。 首先,理解C++中的...
静态分析是在编译阶段进行的,通过检查源代码来查找可能导致内存泄露的模式。动态分析则是在程序运行时进行,通过监控内存分配和释放的行为来识别潜在的内存泄露。 1. 静态分析:工具如Cppcheck和Clang-Tidy可以...
- 虽然智能指针如`std::unique_ptr`和`std::shared_ptr`能自动管理内存,但若未正确使用,也可能导致内存泄漏。我们需要检查代码中智能指针的使用,确保它们能够正确地接管内存的生命周期。 4. **线程安全:** - ...
通过将HEOB与QT Creator结合使用,开发者可以在编写和调试Qt应用程序的过程中,实时监控内存分配和释放,找出可能导致内存泄漏的代码段。 使用HEOB时,首先需要将HEOB的可执行文件(heob32.exe或heob64.exe)添加到...
Boundcheck是一款由NuMega公司开发的专业调试工具,主要用于检测程序中的代码错误,特别是边界检查和内存泄漏问题。在Delphi编程环境中,这款工具发挥了重要作用,帮助开发者在早期阶段发现并修复潜在的问题,从而...
事实上,不当的编程习惯和设计模式仍然会导致内存泄漏,尤其是在资源受限的移动设备上,内存泄漏可能会严重影响应用的性能和用户体验。 #### 1. 造成Android应用程序内存泄漏的原因 ##### 1.1 引用未释放造成的...
"FastMM 定位内存泄露的代码位置.docx" 应该提供了关于如何利用FastMM4提供的信息来追踪和定位导致内存泄漏的具体代码行的技巧。这通常涉及解析泄漏报告,理解报告中的各项指标,并在源代码中找到相应的代码段。 总...