java存在内存泄露吗?怎样模拟java的内存泄露?
java GC机制的存在,没有引用的对象都会被GC。这样的话java存在内存泄露吗?怎样用程序模拟?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
java GC机制的存在,没有引用的对象都会被GC。这样的话java存在内存泄露吗?怎样用程序模拟?
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
接受
或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
发布评论
评论(19)
可以看看这篇文章,虽然看完了我也忘了http://www.ibm.com/developerworks/cn/...
Java也有内存泄露,GC不是万能的。GC会回收没有引用的对象,但是如果你的java程序里存在泄露问题,很多应该被回收的对象仍然被引用,那么就泄露了。
effective java 上有个例子~
你把对象不停的放到 static final 的map中,就泄露了
回复:Anakin
是不是说的这个:
自定义一个栈类,内部用一个数组储存数据,用整数n表示逻辑上用到的位置。当push的数据过多时,扩展数组,n也扩大到指定位置;但当pop数据时,仅仅是减小n,却不清除那些逻辑上不再用到的数据(也就是储存在数组中,并且位置大于n的数据)。
存在。虽然有垃圾回收,但糟糕的编程习惯也会造成内存泄露
举个List的例子。这个List没有被清理干净,就造成了内存泄露,跑一次的程序还好,跑完了内存就释放了,如果是在服务器上一直跑的程序,时间久了,内存就用完了。
在java中因为有垃圾回收器来帮助我们管理内存,所以在正常情况下是不会出现内存泄露的。但垃圾回收器它是jvm虚拟机的一个线程,所以它什么时候执行,不取决于我们,也不取次于jvm。它什么时候执行取决于cpu是否切换到它这个线程,也就是说它是否具备cpu的执行资格,即使具备cpu执行资格也未必会马上执行。因为,如果有多个线程同时都具备cpu执行资格的情况下会造成线程阻塞,因为cpu在同一时间同一时刻只能执行一个线程。所以,如果我们在一段时间内,连续创建对象,分配内存,就会造成内存泄露。最简单的例子:
while(true) {
Userinfo u = new Userinfo(); // 创建一个对象
}
GC只是回收失去引用的对象,但是,由于程序设计失误导致的对象始终被引用,会导致内存泄漏,如下面的代码。用数组实现了一个栈, 支持入栈和出栈操作。
当出栈的时候,没有释放数组对元素的引用,那么将导致这个对象始终被数组引用,那么GC是无法回收此对象占用的内存的。
修改的方案是:
关于此问题,做了一个小小的总结:发布到
http://yanwushu.sinaapp.com/java_gc_and_memory_leak/
欢迎指正
要是想知道个大概的话,搜一下-Xms256M -Xmx2048M,如果你想再更深入,就要看java的内存管理机制,分年老代、年轻代、gc、xms、PermSize、DirectMemorySize……很多参数,之前项目需要深入的了解下内存管理机制,这块配置细化起来很复杂
http://www.cnblogs.com/xiaoysec/p/4345221.html 之前写的一个小实验 希望对你有帮助
当一个对象不再被引用时,GC会回收它。不仅如此,当一个对象是被弱引用(WeakReference),软引用(SoftReference)着,GC也会在适当的时机回收它们。严格的讲,java不存在内存泄露。但是在实际应用中,由于很多对象会被一些拥有全局生命周期的容器所引用,而此时GC并不会回收这些对象。当出现了上述这一情况时,就出现了宽泛意义上的内存泄露。
建议去看看JVM方面的书籍,在Java中是存在内存泄漏的,OutOfMemoryError就是内存泄漏。
栈中的内存泄漏
泄漏如果线程请求的栈深度大于虚拟机所允许的深度,将抛出StackOverflowError异常;如果虚拟机栈可以动态扩展(当前大部分的Java虚拟机都可动态扩展,只不过Java虚拟机规范中也允许固定长度的虚拟机栈),如果扩展时无法申请到足够的内存,就会抛出OutOfMemoryError异常
堆中的内存泄漏
Java堆可以处于物理上不连续的内存空间中,只要逻辑上是连续的即可,就像我们的磁盘空间一样。在实现时,既可以实现成固定大小的,也可以是可扩展的,不过当前主流的虚拟机都是按照可扩展来实现的(通过-Xmx和-Xms控制)。如果在堆中没有内存完成实例分配,并且堆也无法再扩展时,将会抛出OutOfMemoryError异常。
以上引用自 周志明(2013-05-30).深入理解Java虚拟机:JVM高级特性与最佳实践(第2版)
广义上的C/C++的内存泄露包含两种情景:内存失控,内存浪费。
内存失控的问题已经基本被JAVA处理掉了,程序员基本不用担心。
内存浪费是代码的原因,这种意义上的内存泄露在任何语言里都是存在的。
servlet中往线程池的threadlocal放数据,但不删除数据
把对象放到 集合类中很容易 内存泄露。比如:
Vector v=new Vector(10);
for (int i=1;i<100; i++)
{
}
Vector仍然引用该对象,对象不能被回收。解决办法:Vector对象设置为null
可以写一个程序,不断死循环创建对象,启动的时候设定jvm内存大小即可模拟。
长生命周期的对象保存有段生命周期的对象就会发生内存泄露
比如说 你有一个静态的集合,一直add对象,但是没有remove或者clean的策略,导致内存越来越多,你又不知道。其实Java这种内存泄漏 不是真正意义上的泄漏,因为这个内存还是可跟踪的。真正的是C里面的野指针,那个是找不到的。
一般来说指的Java内存泄露是指产生过多无谓的GC
想要模拟的话,很简单: