java存在内存泄露吗?怎样模拟java的内存泄露?

发布于 2022-09-06 09:37:08 字数 57 浏览 29 评论 0

java GC机制的存在,没有引用的对象都会被GC。这样的话java存在内存泄露吗?怎样用程序模拟?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(19

毁我热情 2022-09-13 09:37:08

可以看看这篇文章,虽然看完了我也忘了http://www.ibm.com/developerworks/cn/...

微暖i 2022-09-13 09:37:08

Java也有内存泄露,GC不是万能的。GC会回收没有引用的对象,但是如果你的java程序里存在泄露问题,很多应该被回收的对象仍然被引用,那么就泄露了。

一花一树开 2022-09-13 09:37:08

effective java 上有个例子~

桜花祭 2022-09-13 09:37:08

你把对象不停的放到 static final 的map中,就泄露了

叹倦 2022-09-13 09:37:08

回复:Anakin
是不是说的这个:
自定义一个栈类,内部用一个数组储存数据,用整数n表示逻辑上用到的位置。当push的数据过多时,扩展数组,n也扩大到指定位置;但当pop数据时,仅仅是减小n,却不清除那些逻辑上不再用到的数据(也就是储存在数组中,并且位置大于n的数据)。

韶华倾负 2022-09-13 09:37:08

存在。虽然有垃圾回收,但糟糕的编程习惯也会造成内存泄露
举个List的例子。这个List没有被清理干净,就造成了内存泄露,跑一次的程序还好,跑完了内存就释放了,如果是在服务器上一直跑的程序,时间久了,内存就用完了。

ArrayList arr = new ArrayList();
//添加一些元素到arr中

//清空arr
for(int i=0;i<arr.size;i++){
    arr.remove(i);
}
人海汹涌 2022-09-13 09:37:08

在java中因为有垃圾回收器来帮助我们管理内存,所以在正常情况下是不会出现内存泄露的。但垃圾回收器它是jvm虚拟机的一个线程,所以它什么时候执行,不取决于我们,也不取次于jvm。它什么时候执行取决于cpu是否切换到它这个线程,也就是说它是否具备cpu的执行资格,即使具备cpu执行资格也未必会马上执行。因为,如果有多个线程同时都具备cpu执行资格的情况下会造成线程阻塞,因为cpu在同一时间同一时刻只能执行一个线程。所以,如果我们在一段时间内,连续创建对象,分配内存,就会造成内存泄露。最简单的例子:
while(true) {
Userinfo u = new Userinfo(); // 创建一个对象
}

魔法少女 2022-09-13 09:37:08

GC只是回收失去引用的对象,但是,由于程序设计失误导致的对象始终被引用,会导致内存泄漏,如下面的代码。用数组实现了一个栈, 支持入栈和出栈操作。

import java.util.EmptyStackException;

/**
 * Created by yanwushu@gmail.com on 14-9-21.
 */
public class MyStack {
    private Object[] elements;
    private int Increment = 10;
    private int size = 0;

    public MyStack(int size) {
        elements = new Object[size];
    }

    //入栈
    public void push(Object o) {
        capacity();
        elements[size++] = o;
    }

    //出栈
    public Object pop() {
        if (size == 0)
            throw new EmptyStackException();
        Object o = elements[--size];
        return o;
    }

    //增加栈的容量
    private void capacity() {
        if (elements.length != size)
            return;
        Object[] newArray = new Object[elements.length + Increment];
        System.arraycopy(elements, 0, newArray, 0, size);
    }

    public static void main(String[] args) {
        MyStack stack = new MyStack(100);
        for (int i = 0; i < 100; i++)
            stack.push(new Integer(i));
        for (int i = 0; i < 100; i++) {
            System.out.println(stack.pop().toString());
        }
    }
}

当出栈的时候,没有释放数组对元素的引用,那么将导致这个对象始终被数组引用,那么GC是无法回收此对象占用的内存的。

修改的方案是:

   //出栈
    public Object pop() {
        if (size == 0)
            throw new EmptyStackException();
        Object o = elements[--size];
        elements[size] = null; //释放引用
        return o;
    }

关于此问题,做了一个小小的总结:发布到

http://yanwushu.sinaapp.com/java_gc_and_memory_leak/

欢迎指正

把梦留给海 2022-09-13 09:37:08

要是想知道个大概的话,搜一下-Xms256M -Xmx2048M,如果你想再更深入,就要看java的内存管理机制,分年老代、年轻代、gc、xms、PermSize、DirectMemorySize……很多参数,之前项目需要深入的了解下内存管理机制,这块配置细化起来很复杂

烟雨凡馨 2022-09-13 09:37:08

http://www.cnblogs.com/xiaoysec/p/4345221.html 之前写的一个小实验 希望对你有帮助

风铃鹿 2022-09-13 09:37:08

当一个对象不再被引用时,GC会回收它。不仅如此,当一个对象是被弱引用(WeakReference),软引用(SoftReference)着,GC也会在适当的时机回收它们。严格的讲,java不存在内存泄露。但是在实际应用中,由于很多对象会被一些拥有全局生命周期的容器所引用,而此时GC并不会回收这些对象。当出现了上述这一情况时,就出现了宽泛意义上的内存泄露。

倾城泪 2022-09-13 09:37:08

建议去看看JVM方面的书籍,在Java中是存在内存泄漏的,OutOfMemoryError就是内存泄漏。
栈中的内存泄漏
泄漏如果线程请求的栈深度大于虚拟机所允许的深度,将抛出StackOverflowError异常;如果虚拟机栈可以动态扩展(当前大部分的Java虚拟机都可动态扩展,只不过Java虚拟机规范中也允许固定长度的虚拟机栈),如果扩展时无法申请到足够的内存,就会抛出OutOfMemoryError异常
堆中的内存泄漏
Java堆可以处于物理上不连续的内存空间中,只要逻辑上是连续的即可,就像我们的磁盘空间一样。在实现时,既可以实现成固定大小的,也可以是可扩展的,不过当前主流的虚拟机都是按照可扩展来实现的(通过-Xmx和-Xms控制)。如果在堆中没有内存完成实例分配,并且堆也无法再扩展时,将会抛出OutOfMemoryError异常。

以上引用自 周志明(2013-05-30).深入理解Java虚拟机:JVM高级特性与最佳实践(第2版)

野の 2022-09-13 09:37:08

广义上的C/C++的内存泄露包含两种情景:内存失控,内存浪费。

内存失控的问题已经基本被JAVA处理掉了,程序员基本不用担心。

内存浪费是代码的原因,这种意义上的内存泄露在任何语言里都是存在的。

我是男神闪亮亮 2022-09-13 09:37:08

servlet中往线程池的threadlocal放数据,但不删除数据

吾家有女初长成 2022-09-13 09:37:08

把对象放到 集合类中很容易 内存泄露。比如:

Vector v=new Vector(10);
for (int i=1;i<100; i++)
{

Object o=new Object();
v.add(o);
o=null;    

}
Vector仍然引用该对象,对象不能被回收。解决办法:Vector对象设置为null

遇见了你 2022-09-13 09:37:08

可以写一个程序,不断死循环创建对象,启动的时候设定jvm内存大小即可模拟。

我是男神闪亮亮 2022-09-13 09:37:08

长生命周期的对象保存有段生命周期的对象就会发生内存泄露

ぶ宁プ宁ぶ 2022-09-13 09:37:08

比如说 你有一个静态的集合,一直add对象,但是没有remove或者clean的策略,导致内存越来越多,你又不知道。其实Java这种内存泄漏 不是真正意义上的泄漏,因为这个内存还是可跟踪的。真正的是C里面的野指针,那个是找不到的。

送你一个梦 2022-09-13 09:37:08

一般来说指的Java内存泄露是指产生过多无谓的GC

想要模拟的话,很简单:

String a = new String("lol ");

for (int i=0; i<100000; ++i)
{
    a += a;
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文