理论上Java因为有垃圾回收机制(GC)不会存在内存泄露问题(这也是Java被广泛使用于服务器端编程的一个重要原因);然而在实际开发中,可能会存在无用但可达的对象,这些对象不能被GC回收,因此也会导致内存泄露的发生。例如hibernate的Session(一级缓存)中的对象属于持久态,垃圾回收器是不会回收这些对象的,然而这些对象中可能存在无用的垃圾对象,如果不及时关闭(close)或清空(flush)一级缓存就可能导致内存泄露。下面例子中的代码也会导致内存泄露。

package com.dx.test;

import java.util.Arrays;
import java.util.EmptyStackException; public class MyStack<T> {
private T[] elements;
private int size = 0; private static final int INIT_CAPACITY = 16; public MyStack() {
elements = (T[]) new Object[INIT_CAPACITY];
} public void push(T elem) {
ensureCapacity();
elements[size++] = elem;
} public T pop() {
if (size == 0)
throw new EmptyStackException();
return elements[--size];
} public int length() {
return elements.length;
} public void test(int top){
StringBuffer buffer=new StringBuffer();
for(int i=0;i<top;i++){
buffer.append(elements[i]+",");
} System.out.println(buffer.toString());
} private void ensureCapacity() {
if (elements.length == size) {
elements = Arrays.copyOf(elements, 2 * size + 1);
}
}
}

测试代码:

package com.dx.test;

import java.io.IOException;

public class TestMain {
public static void main(String[] args) throws IOException {
System.out.println("start");
MyStack<Integer> items = new MyStack<Integer>();
for (int i = 0; i < 100000; i++) {
items.push(i);
} for (int i = 0; i < 100000; i++) {
items.pop();
} System.out.println(items.length());
items.test(100); System.out.println("complete...");
}
}

从打印结果中我们就可以发现问题:

start
139263
0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,
complete...

上面的代码实现了一个栈(先进后出(FILO))结构,乍看之下似乎没有什么明显的问题,它甚至可以通过你编写的各种单元测试。然而其中的pop方法却存在内存泄露的问题,当我们用pop方法弹出栈中的对象时,该对象不会被当作垃圾回收,即使使用栈的程序不再引用这些对象,因为栈内部维护着对这些对象的过期引用(obsolete reference)。在支持垃圾回收的语言中,内存泄露是很隐蔽的,这种内存泄露其实就是无意识的对象保持。如果一个对象引用被无意识的保留起来了,那么垃圾回收器不会处理这个对象,也不会处理该对象引用的其他对象,即使这样的对象只有少数几个,也可能会导致很多的对象被排除在垃圾回收之外,从而对性能造成重大影响,极端情况下会引发Disk Paging(物理内存与硬盘的虚拟内存交换数据),甚至造成OutOfMemoryError。

Java:Java 中会存在内存泄漏吗的更多相关文章

  1. Android中常见的内存泄漏

    为什么会产生内存泄漏? 当一个对象已经不需要再使用了,本该被回收时,而有另外一个正在使用的对象持有它的引用从而导致它不能被回收,这导致本该被回收的对象不能被回收而停留在堆内存中,这就产生了内存泄漏. ...

  2. Java中如何防止内存泄漏的发生

    在Java开发中我们常常会遇到内存泄漏的情况发生.那么为什么会发生内存泄漏,以及怎样去防止! 内存泄漏的定义:对象已经没有被应用程序使用,但是垃圾回收器没办法移除它们,因为还在被引用着. 为什么会发生 ...

  3. java中存在的内存泄漏

    大家都知道JAVA有着自己的优点---垃圾回收器的机制,这个开发人员带来了很大的方便,不用我们编程人员去 控制内存回收等问题,有效的解决了内存泄露的问题,不至于导致系统因内存问题崩溃.为了精确的回收内 ...

  4. Java匿名对象导致的内存泄漏

    这几天与在某群与群友讨论了Runnable匿名对象导致内存泄漏的相关问题,特此记录一下. 示例代码如下: package com.memleak.memleakdemo; public class L ...

  5. 利用Java剖析工具JProfiler查找内存泄漏的方法

    本文主要介绍如何如何利用在使用JProfiler时意识到内存泄漏以及查找内存泄漏的几种方法. 工具/原料   JProfiler 方法/步骤   JProfiler的内存视图会话提供了内存使用情况的动 ...

  6. android 中如何分析内存泄漏

    转载:http://blog.csdn.net/fulinwsuafcie/article/details/8363218 前提条件: 1,电脑安装了java 运行环境 2,手机端开启了 USB 调试 ...

  7. android中常见的内存泄漏和解决的方法

    android中的内存溢出预计大多数人在写代码的时候都出现过,事实上突然认为工作一年和工作三年的差别是什么呢.事实上干的工作或许都一样,产品汪看到的结果也都一样,那差别就是速度和质量了. 写在前面的一 ...

  8. String中substring方法内存泄漏问题

    众所周知,JDK中以前String类中的substring方法存在内存泄漏问题,之所以说是以前,是因为JDK1.7及以后的版本已经修复了,我看都说JDK1.6的版本也存在这个问题,但是我本机上安装的1 ...

  9. .NET中常见的内存泄漏和解决办法

    在.NET中,虽然CLR的GC垃圾回收器帮我们自动回收托管堆对象,释放内存,最大程度避免了"内存泄漏"(应用程序所占用的内存没有得到及时释放),但.NET应用程序"内存泄 ...

  10. Js中常见的内存泄漏场景

    常见的内存泄漏场景 内存泄漏Memory Leak是指程序中已动态分配的堆内存由于疏忽或错误等原因程序未释放或无法释放,造成系统内存的浪费,导致程序运行速度减慢甚至系统崩溃等严重后果.内存泄漏并非指内 ...

随机推荐

  1. 轮评审用例,写用例的重要性-----(python单元测试反思)

    时间过的真快,3月底了,更新一次博客吧,算是对三月份忙碌的一个总结. 吃过饭,习惯登录qq,看到我群里的一个大神,碎冰发的一个作业 不就是写个代码吗,然后写完再进行测试这个代码是否实现了这个功能. 于 ...

  2. ASP.NET Core Web 支付功能接入 支付宝-电脑网页支付篇

    这篇文章将介绍ASP.NET Core中使用 开源项目 Payment,实现接入支付宝-电脑网页支付接口及同步跳转及异步通知功能. 开发环境:Win 10 x64.VS2017 15.6.4..NET ...

  3. three.js 实现全景以及优化(1)

    实现一个三维全景;  然后思考优化问题; 于是我问了下webgl技术交流群朋友有啥解决方案; 对于krpano.js 的了解,只是知道百度全景用了这个技术; 最后还是选择了群友给出的three.js  ...

  4. javascript中函数的闭包自调用

    话不多说, 直接上代码 // 定义一个变量outerParam, 然后使用一个闭包函数给该变量初始化var outerParam = (function testClosure(param) { // ...

  5. Java TimSort算法 源码 笔记

    本来准备看Java容器源码的.但是看到一开始发现Arrays这个类我不是很熟,就顺便把Arrays这个类给看了.Arrays类没有什么架构与难点,但Arrays涉及到的两个排序算法似乎很有意思.那顺便 ...

  6. Linux 绝对路径与相对路径

    根据文件名写法的不同,可将所谓的路径(path)定义为绝对路径(absolute)和相对路径(relative). 绝对路径:由根目录(/)开始写起的文件名或目录名称. 相对路径:相对于当前路径的文件 ...

  7. 【SSH/SFTP】SSH协议和SFTP

    [SSH和SFTP] ■ 设置一个只允许访问部分目录的SFTP服务器 由于SSH和SFTP之间的紧密联系,一个SFTP服务器必然会导致开放一定的SSH服务,而SSH的风险显然比SFTP要大一些.自然, ...

  8. C++引用指针 & 构造函数

    近来回转 C++的学习,脑子又被搞得了一团迷(简直不要忘得太快.....    ) 过后静下来想一想,还是因为有些东西没搞清楚导致,所以理了理两个容易搞迷糊的地方. 1. 引用与指针 C++进行传值更 ...

  9. Algorithm --> KMP算法

    KMP算法 一.传统字符串匹配算法 /* * 从s中第sIndex位置开始匹配p * 若匹配成功,返回s中模式串p的起始index * 若匹配失败,返回-1 */ ) { ; || p.length( ...

  10. 将 Shiro 作为应用的权限基础 一:shiro的整体架构

    将 Shiro 作为应用的权限基础 一:shiro的整体架构 近来在做一个重量级的项目,其中权限.日志.报表.工作量由我负责,工作量还是蛮大的,不过想那么多干嘛,做就是了. 这段时间,接触的东西挺多, ...