`
robinjoe
  • 浏览: 45806 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

【转】Java高级进阶学习-Java的内存回收(4)

阅读更多

对于c++程序来说,对象占用的内存空间都必须由程序显式回收,如果程序员忘记了回收它们,那它们所占用的内存空间就会产生内存泄漏;对于java程序来说,所有不可达的对象都由垃圾回收机制负责回收,因此程序员不需要考虑这部分的内存泄漏。但如果程序中有一些java对象,它们处于可达状态,但程序以后永远都不会再访问它们,那它们所占用的空间也不会被回收,它们所占用的空间也会产生内存泄漏.
例如,如下图中
有ArrayList的长度是4,有四个元素“网”,“络”,“时”,“空”,当我们删除了ArrayList中的"网"这个元素时,它的size等于3,也就是该ArrayList认为自己只有3个元素,因此它永远也不会去访问底层数组的第4个元素。对于程序本身来说,这个对象已经变成了垃圾,但对于垃圾回收机制来说,这个对象依然处于可达状态,因此不会回收它,这就产生了内存泄漏了

Java高级进阶学习-Java的内存回收(4)

Java高级进阶学习-Java的内存回收(4)

其实解决方法也很简单,程序员显式赋值让 “网”对应的字符串对象 为 null 就行了

 

再看下面程序采用基于数组的方式实现了一个Stack,大家可以找找这个程序中的内存泄漏
public class Stack
{
//存放栈内元素的数组
private Object[] elementData;
//记录栈内元素的个数
private int size = 0;
private int capacityIncrement;
//以指定初始化容量创建一个Stack
public Stack(int initialCapacity)
{
elementData = new Object[initialCapacity];
}
public Stack(int initialCapacity , int capacityIncrement)
{
this(initialCapacity);
this.capacityIncrement = capacityIncrement;
}
//向“栈”顶压入一个元素
public void push(Object object)
{
ensureCapacity();
elementData[size++] = object;
// if(size==10) System.out.println("size="+size);
}
public Object pop()
{
if(size == 0)
{
throw new RuntimeException("空栈异常");
}
return elementData[--size];
}

public int size()
{
return size;
}
//保证底层数组能容纳栈内所有元素
private void ensureCapacity()
{
//增加堆栈的容量
if(elementData.length==size)
{
Object[] oldElements = elementData;
int newLength = 0;
//已经设置capacityIncrement
if (capacityIncrement > 0)
{
newLength = elementData.length + capacityIncrement;
}
else
{
//将长度扩充到原来的1.5倍
newLength = (int)(elementData.length * 1.5);
}
// System.out.println("newLength="+newLength);
elementData = new Object[newLength];
//将原数组的元素复制到新数组中
System.arraycopy(oldElements , 0 , elementData , 0 , size);
}
}
public static void main(String[] args)
{
Stack stack = new Stack(10);
//向栈顶压入10个元素
for (int i = 0 ; i < 10 ; i++)
{
stack.push("元素" + i);
}
//依次弹出10个元素
for (int i = 0 ; i < 10 ; i++)
{
System.out.println(stack.pop());
}
}
}


  上面程序实现了一个简单的Stack,并为这个Stack实现了push(),pop()两个方法,其中pop()方法可能产生内存泄漏。为了说明这个Stack的内存泄漏,程序main方法创建了一个Stack对象,先向该Stack压入10个元素。注意:此时底层elementData的长度为10,每人数组元素都引用一个字符串。
  接下来,程序10次调用pop()方法弹出栈顶元素。注意pop()方法产生的内存泄漏,它只做了两件事:一是修饰Stack的size属性,也就是记录栈内元素减1,二是返回elementData数组中索引为size-1的元素

  也就是说,每调用pop方法一次,Stack会记录该栈的尺寸减1,但未清除elementData数组的最后一个元素的引用,这样就会产生内存泄漏。类似地,也应该按ArrayList类的源代码改写此处pop()方法的源代码,如下所示
public Object pop()
{
if(size == 0)
{
throw new RuntimeException("空栈异常");
}
Object obj=elementData[--size];
//清除最后一个数组元素的引用,避免内存泄漏
elementData[size]=null;
return obj;
}

 

转自:http://hi.baidu.com/javabbs/blog/item/a538c0883e602599a4c2728e.html

分享到:
评论

相关推荐

    Java语言程序设计-进阶篇-原书第8版

    以下是一些Java进阶编程中常见的知识点: 1. 面向对象的高级特性:包括继承、封装、多态的深入理解,以及抽象类和接口的使用,泛型编程,注解以及反射机制。 2. Java集合框架:深入学习List、Set、Map等集合接口的...

    重塑java基础高级进阶资源分享

    根据提供的文件信息,我们可以推断出这是一份关于Java编程语言高级进阶的学习资源分享。虽然分享者在描述中提到“仅仅是分享!实在没有c币可以留言我,我可以私发”,这里的“c币”可能是指某个社区或平台内的虚拟...

    java高级进阶知识

    2. **垃圾回收机制**:Java的自动内存管理依赖于垃圾回收,包括新生代GC、老年代GC、全停顿GC等策略。理解这些机制有助于我们优化内存使用,减少垃圾回收带来的性能影响。 3. **类加载机制**:JVM的类加载过程包括...

    java经典面试题目-面经-java-Java语言的进阶概念-常用的库和框架-并发编程-网络编程-Web开发-面经

    Java的垃圾回收(GC)自动管理内存,回收不再使用的对象所占用的空间。手动触发GC可以通过`System.gc()`,但不推荐,因为GC策略由JVM管理,频繁调用可能导致性能下降。 设计模式是解决软件设计中常见问题的模板,如...

    Java进阶学习资料.zip

    在Java进阶学习中,你需要掌握以下几个关键的知识点: 1. 高级数据结构与算法:理解并能熟练运用ArrayList、LinkedList、HashMap等集合框架,深入研究Set、Queue、Stack等接口及其实现类。同时,学习并应用高级排序...

    Java高级进阶面试题目.pdf

    标题“Java高级进阶面试题目.pdf”表明这是一份涵盖Java高级技术点的面试题资料,它适用于那些寻求在Java领域深入发展的求职者或者技术提升者。描述中的“Java高级进阶面试题目”进一步细化了这份资料的定位,即为...

    java 高级架构进阶学习

    ### Java高级架构进阶学习知识点概述 #### 一、思维导图 - **知识点概览**:思维导图是理解Java高级架构的关键工具之一。它能够帮助开发者快速掌握架构设计的核心概念和技术要点。 - **核心内容**: - **基础知识...

    Java面向对象(进阶)- Object类的详细概述

    在Java编程语言中,面向对象是其核心特性之一。Object类是所有Java类的根父类,无论何时我们创建一个新的类,除非明确指定其他父类,否则它都会默认继承Object类。这使得Object类中的方法对所有Java类都可用,体现了...

    java大神进阶之路.pdf

    Java大神进阶之路是一份针对Java开发者进阶提升的学习指南,详细描述了从编程基础到Java语言本身的精通,再到数据库以及Java Web核心技术的掌握,以及每个阶段所需要学习和掌握的知识点。文中特别强调了数据结构和...

    java学习资料-免费-适合0基础&进阶学习

    2. **进阶Java技术**: - **集合框架**:深入学习ArrayList、LinkedList、HashSet、HashMap等数据结构的实现和应用场景。 - **多线程**:了解并发编程,包括线程的创建、同步机制(如synchronized关键字、Lock接口...

    1 Java 程序员进阶之路(暗黑版)1

    【Java程序员进阶之路(暗黑版)1】是一篇专为Java爱好者设计的进阶教程,旨在通过详细且通俗易懂的方式,帮助读者提升Java...本专栏通过实例和故事化的讲解,使得学习过程更加生动有趣,是进阶Java程序员的理想资源。

    java进阶提高学习教程-13JVM与多线程.pptx

    Java进阶学习教程中的第13章主要涵盖了JVM(Java虚拟机)和多线程两个核心概念。JVM是Java程序运行的基础,它负责解释执行字节码文件,并提供了Java语言的跨平台特性。Java程序通过JVM与操作系统交互,使得程序可以...

    Java语言程序设计-进阶篇(原书第8版)

    《Java语言程序设计-进阶篇》是Java编程学习的重要参考资料,尤其对于已经掌握Java基础知识的开发者来说,这本书是进一步提升技能的关键。该书的第八版涵盖了Java编程的诸多高级主题,旨在帮助读者深入理解Java的...

    Java语言程序设计-进阶篇(原书第10版 中英文)

    4. 内存管理:Java的垃圾回收机制使得程序员无需手动管理内存,但理解其工作原理对于优化程序性能至关重要。本书会解释如何合理使用对象,避免内存泄漏。 二、高级特性 5. 泛型:泛型是Java 5引入的新特性,用于...

    2021 Java架构进阶 Nginx企业级教程.txt打包整理.zip

    标题"2021 Java架构进阶 Nginx企业级教程.txt打包整理.zip"表明这是一个关于Java架构进阶和Nginx企业级应用的教程集合,内容可能涵盖Java技术栈的高级应用、系统架构设计以及Nginx服务器的配置和优化。.txt格式的...

    Java语言程序设计-进阶篇(原书第10版).pdf

    《Java语言程序设计-进阶篇》是针对已经掌握Java编程基础的学习者提供的一本深入学习书籍,尤其适合想要提升编程技巧和理解高级特性的读者。这本书基于原书的第10版,意味着它涵盖了最新的Java版本特性,比如Java 8...

    java程序设计进阶版

    《Java程序设计进阶版》原书第10版是一本深入探讨Java编程技术的权威著作,适合已经掌握基础Java知识的学习者进一步提升技能。这本书以其高清晰度和完整的章节结构,为读者提供了丰富的学习资源,是Java程序员进阶...

    Java进阶.zip

    "Java进阶"这个主题涵盖了Java开发中的高级概念和技术,旨在帮助程序员深入理解Java的精髓,提升开发技能。SunJava.pdf可能包含的是由Sun Microsystems(Java的原始开发者)发布的官方文档或教程。 1. **内存管理与...

    java2进阶教程

    JVM(Java虚拟机)是Java程序的运行环境,理解它的内存模型、类加载机制、垃圾回收原理以及性能优化技巧,如堆内存配置、栈内存优化、方法区调整等,对提升程序性能至关重要。 最后,数据库交互通常使用JDBC(Java ...

    Java语言程序设计-基础篇-进阶篇源码

    本资源包含了“Java语言程序设计-基础篇”和“Java语言程序设计-进阶篇”的全部源码,是学习和深入理解Java编程的理想资料。 在基础篇中,主要涵盖了以下知识点: 1. **Java简介**:Java的历史、特性,以及为什么...

Global site tag (gtag.js) - Google Analytics