有什么办法可以查出内存泄漏(OutOfMemory)发生在什么地方?

starry11 2005-03-01 04:15:42
开发的系统内有若干个进程一直在运行,进行周期性的监测和操作,可是发现运行一个小时左右就发生OutOfMemory 错误,进程不再运行。

用 -verbosegc 观察,发现内存占用量一直都在上升,直到最后几乎用完64M为止。

数据库的操作是用hibernate来实现的,进程要做的事情是查询数据表记录,生成文件,再发送出去,不知道什么地方有可能导致内存泄漏?
会出现 WARN : finalizing unclosed session with closed connection
有可能是这个导致的吗?我是用dbcp连接池去管理数据库连接的。

另外,有时即使不发生OutOfMemory的错误,进程都会停止运行,不知道这有可能是因为什么原因?
...全文
587 19 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
19 条回复
切换为时间正序
请发表友善的回复…
发表回复
starry11 2005-03-04
  • 打赏
  • 举报
回复
谢谢 CAYU(中原) 的热心指点,解决了我不少疑惑

仔细看了一下optimizeit profile的问题分析,消耗内存不正常增长的主要有两个地方,一个是 Xml处理时候的XPath :BaseXPath.selectNodesForContext ;还有一个是hibernate的 Configuration.buildSessionFactory。

另外生成xml文件时也很占内存,不过发生次数不多。

我想我用hibernate也许还不够正确,有时会发生WARN : unclosed connection
XPath也不应该发生问题才对

唉 不知道哪里不对……继续查……
jspxnet 2005-03-03
  • 打赏
  • 举报
回复
java 组件几乎都是独立的不兼容之类的问题不太可能,除非是weblogic 才有可能.
dbcp和c3p0都不过是个连接池,要不要,用不用都没什么关系的.用那个更不是问题了。
jspxnet 2005-03-03
  • 打赏
  • 举报
回复
1.connection 在一定的时间后会自动关闭,c3p0 会检测是否已经关闭,如果关闭了就重新得到一个connection ,如果使用其它的连接池,很多都没有对这个进行处理.比如prxool也没有处理这个问题.

2.如果你经常发生空指针错误,说明你的程序在处理空指针上有问题,就必须检查你的代码了.

3.JVM内存回收时间会比较长的,并不是你使用了,JVM马上就回收,(部分比较临时的对象会马上回收),
但你从计算机的任务管理器数字上是看不出来的,JVM的回收一般是使用快到你的最大上限才回收.
比如你是 64M 他会慢慢的用完这64M,感觉快没了的时候才回收.

4.hibernate 最好在128M以上.

5.写java程序如果老发生内存问题,你可是部分工具检测一下Optimizeit ,profile 都可以,
在运行一定时间后,你看java 对象,没有释放的,实例对象最多的就是最有可能出现问题的部分.
starry11 2005-03-03
  • 打赏
  • 举报
回复
补充一句,我是用tomcat的,tomcat使用的是dbcp,如果系统用c3p0,就会发生不兼容之类的问题啊?
starry11 2005-03-03
  • 打赏
  • 举报
回复
谢谢 CAYU(中原) 的解答

我原来是用c3p0 连接池的,但经常发生空指针错误,在实在找不到原因的情况下,我改用了dbcp,就没有再发生空指针的问题了

不知道用c3p0和用dbcp,有什么不一样的?

我运行的默认内存是64M ,其实程序运行所需要的内存是很少的,但感觉是不能完全回收,逐渐积累,才发生oom问题

现在就是查不出哪里有问题,更糟糕的是出现了 WARN : unclosed connection

sigh……
jspxnet 2005-03-03
  • 打赏
  • 举报
回复
1.你的连接池有问题 改用c3p 连接池.
2.如果你不期望内存太大,使用Session后,关闭时先clear().[在计算机内存很小的情况下]
3.jvm 默认提供的内存时16M如果的程序使用的内存大于这个值就会 OutOfMemory.
所以你有必要加大jvm 的内存 使用参数 -Xms512M -Xmx1g
4.在程序中,对象使用后相互之间不要存在引用,jvm 会自己释放内存.

starry11 2005-03-03
  • 打赏
  • 举报
回复
修改了一下程序,学着hibernate文档里面的,独立出一个HibernateUtil.java ,专门管理SessionFactory 和 Session 。没有再出现 WARN : finalizing unclosed session with closed connection

可是占用的内存仍然持续增大,不知道怎么样才能查出内存泄漏之处?

高手在哪啊?
starry11 2005-03-02
  • 打赏
  • 举报
回复
终于知道怎么用了,应该是 profile, 我怎么老喜欢走弯路呢,嘿嘿

不过到底怎么用,还要进一步摸索

也希望有经验的高手指点一二,谢谢
starry11 2005-03-02
  • 打赏
  • 举报
回复
摸索了一下,应该是在Progress Tracker 里面查看内存使用情况吧?

可是还是不会用…… :(
congbailing_914 2005-03-02
  • 打赏
  • 举报
回复
顶一下!
starry11 2005-03-02
  • 打赏
  • 举报
回复
装好了 Borland Optimizeit Suit 6.0 ,可是找不到地方观察内存的使用情况,是Thread Debugger么?

我可以监测线程的运行情况,但没有办法观察内存使用的变化啊
starry11 2005-03-02
  • 打赏
  • 举报
回复
下载了一个 Borland Optimizeit Suit 6.0 版本的,可是找不到注册码,有谁有么?
bonbonice 2005-03-02
  • 打赏
  • 举报
回复
starry11 2005-03-02
  • 打赏
  • 举报
回复
咔咔 想学学新东西嘛
的确不怎么清楚hibernate的运作

那就有请eww(fs)指点指点?^_^
eww 2005-03-01
  • 打赏
  • 举报
回复
你胆子真大,都不会hibernate也敢用???上面的错误就出在你的hibernate,内存也是。
rower203 2005-03-01
  • 打赏
  • 举报
回复
optimizeit 工具查漏好用。在网上搜一下好了。
starry11 2005-03-01
  • 打赏
  • 举报
回复
optimizeit是什么?

我是用eclipse开发的

唉,第一次Full GC可以压缩到30多M,可是现在Full GC只能压缩到40多M,看来还有些地方内存泄漏没有查到

该怎么查呢?
liuchunjp 2005-03-01
  • 打赏
  • 举报
回复
利用optimizeit检测项目中几个常用的类的使用状况
starry11 2005-03-01
  • 打赏
  • 举报
回复
修改了一下程序,加强了session的关闭管理

发现当内存用了50多M的时候,会发生一次Full GC,使占用的内存下降到30多M

看样子似乎控制了一些了,但觉得不应该占用那么多内存啊

有经验的高手指点指点?谢谢 ^_^
初识Visual Leak Detector   灵活自由是C/C++语言的一大特色,而这也为C/C++程序员出了一个难题。当程序越来越复杂时,内存的管理也会变得越加复杂,稍有不慎就会出现内存问题。内存泄漏是最常见的内存问题之一。内存泄漏如果不是很严重,在短时间内对程序不会有太大的影响,这也使得内存泄漏问题有很强的隐蔽性,不容易被发现。然而不管内存泄漏多么轻微,当程序长时间运行时,其破坏力是惊人的,从性能下降到内存耗尽,甚至会影响到其他程序的正常运行。另外内存问题的一个共同特点是,内存问题本身并不会有很明显的现象,当有异常现象出现时已时过境迁,其现场已非出现问题时的现场了,这给调试内存问题带来了很大的难度。   Visual Leak Detector是一款用于Visual C++的免费的内存泄露检测工具。相比较其它的内存泄露检测工具,它在检测到内存泄漏的同时,还具有如下特点:   1、 可以得到内存泄漏点的调用堆栈,如果可以的话,还可以得到其所在文件及行号;   2、 可以得到泄露内存的完整数据;   3、 可以设置内存泄露报告的级别;   4、 它是一个已经打包的lib,使用时无须编译它的源代码。而对于使用者自己的代码,也只需要做很小的改动;   5、 他的源代码使用GNU许可发布,并有详尽的文档及注释。对于想深入了解堆内存管理的读者,是一个不错的选择。   可见,从使用角度来讲,Visual Leak Detector简单易用,对于使用者自己的代码,唯一的修改是#include Visual Leak Detector的头文件后正常运行自己的程序,就可以发现内存问题。从研究的角度来讲,如果深入Visual Leak Detector源代码,可以学习到堆内存分配与释放的原理、内存泄漏检测的原理及内存操作的常用技巧等。   本文首先将介绍Visual Leak Detector的使用方法与步骤,然后再和读者一起初步的研究Visual Leak Detector的源代码,去了解Visual Leak Detector的工作原理。   使用Visual Leak Detector(1.0)   下面让我们来介绍如何使用这个小巧的工具。   首先从网站上下载zip包,解压之后得到vld.h, vldapi.h, vld.lib, vldmt.lib, vldmtdll.lib, dbghelp.dll等文件。将.h文件拷贝到Visual C++的默认include目录下,将.lib文件拷贝到Visual C++的默认lib目录下,便安装完成了。因为版本问题,如果使用windows 2000或者以前的版本,需要将dbghelp.dll拷贝到你的程序的运行目录下,或其他可以引用到的目录。   接下来需要将其加入到自己的代码中。方法很简单,只要在包含入口函数的.cpp文件中包含vld.h就可以。如果这个cpp文件包含了stdafx.h,则将包含vld.h的语句放在stdafx.h的包含语句之后,否则放在最前面。如下是一个示例程序:   #include   void main()   {   …   }   接下来让我们来演示如何使用Visual Leak Detector检测内存泄漏。下面是一个简单的程序,用new分配了一个int大小的堆内存,并没有释放。其申请的内存地址用printf输出到屏幕上。   #include   #include   #include   void f()   {   int *p = new int(0x12345678);   printf("p=%08x, ", p);   }   void main()   {   f();   }   编译运行后,在标准输出窗口得到:   p=003a89c0   在Visual C++的Output窗口得到:   WARNING: Visual Leak Detector detected memory leaks!   ---------- Block 57 at 0x003A89C0: 4 bytes ---------- --57号块0x003A89C0地址泄漏了4个字节   Call Stack: --下面是调用堆栈   d:\test\testvldconsole\testvldconsole\main.cpp (7): f --表示在main.cpp第7行的f()函数   d:\test\testvldconsole\testvldconsole\main.cpp (14): main –双击以引导至对应代码处   f:\rtm\vctools\crt_bld\self_x8

62,630

社区成员

发帖
与我相关
我的任务
社区描述
Java 2 Standard Edition
社区管理员
  • Java SE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧