`
jinyanhui2008
  • 浏览: 312908 次
  • 性别: Icon_minigender_1
  • 来自: 青岛
社区版块
存档分类
最新评论

关于java堆栈溢出的那些事

    博客分类:
  • Java
阅读更多

java.lang.OutOfMemoryError: Java heap space

在java程序运行中可能会报如上的错误,通常是在运行过程中内存占用了没有别释放造成的。

以前可能没法跟踪可能是很痛苦的事情,现在好了,我们有一个调试软件可以用了,在生产环境下使用的jRockit软件进行调试,是oracle公司出品的。

前两天试用了一下真的很不错。

前阵子有个程序跑2个礼拜左右就会堆栈溢出,始终找不到头绪,后来使用jrockit才找到问题的出处。

jrockit是可以调试远程程序也可以调试本地程序的。

具体调试步骤

(一)

启动调试程序

 

如果是调试本地程序的话,启动jrockit,然后启动本地需要调试的程序,会在左侧工具栏 本地目录下创建一个连接为需要调试的程序,在上面点击右键,就会启动跟踪。

如何跟踪呢,我的办法就是等,在跟踪开始后,进行截图,然后等程序运行一段时间后查找堆增长比较大的并且一直没有释放的变量。

(二)

然后在上面点击右键,显示分配跟踪。

(三)

然后找到对应的方法,然后就去找问题吧,看看是不是那个地方有内存一直没有释放啊。

 

然后说点我自己的小经验,也许是不对的,但是我在我的应用里面确实是有效的。

 

在经常需要调用的地方将变量设成全局的甚至是静态的,我的操作是设成全局的了。图省事呢。呵呵,因为我的变量时全局都要调用的而且是频繁调用的。

用完的变量一定要记得让它等于null,否则执行gc()貌似是不给回收的。

基本上jrockit跟踪是很强的,都能够找到你的问题所在,要仔细观察,改完程序后记得再重新跟踪下直到没有内存泄露为止。

写完手工。

题外话,写多线程的时候建议使用线程池来操作。

分享到:
评论
28 楼 lichuan 2009-09-07  
大家回帖时,请注意语言表达谨慎,正确,简练。语言例如 “我记不得了”,“我忘了”,“随便看了一看”,给读者一种十分不专业的印象,也无益与培养软件工程师的职业精神。
27 楼 vinter 2009-09-07  
我一直在用JProfiler,感觉挺好用的,
26 楼 jinyanhui2008 2009-09-07  
<div class="quote_title">凤舞凰扬 写道</div>
<div class="quote_div">
<div class="quote_title">hsbljyy 写道</div>
<div class="quote_div">
<div class="quote_title">jinyanhui2008 写道</div>
<div class="quote_div">
<p>在经常需要调用的地方将变量设成全局的甚至是静态的,我的操作是设成全局的了。图省事呢。呵呵,因为我的变量时全局都要调用的而且是频繁调用的。</p>
<p>用完的变量一定要记得让它等于null,否则执行gc()貌似是不给回收的。</p>
</div>
<p><br>不是很明白你这句话中的全局变量指的是什么。如果指的是对象范围内的全局变量,那么在这个对象没有被外部引用的时候,gc应该会处理好这些关系。没有被gc回收的原因肯定是你这个变量指向的对象还存在其他的引用,用static修饰的也一样,除非你用的是static final修饰。</p>
<p> </p>
</div>
<p>    一般来说,全局变量指的就是类的可变属性,也就是你所说的对象范围内的全局变量。同时纠正一点,static的变量是存储在PermGen空间中,而不是heap中(当然了,static变量所引用的对象是会可能在Heap中的),PermGen过大也会超出内存溢出的错误。并且static变量引用的对象属于根引用的序列中,所以即使没有了任何其他引用,一样不会被GC回收,所以你举的这个例子是不对的。</p>
</div>
<p>哦。明白了一点</p>
25 楼 凤舞凰扬 2009-09-07  
<div class="quote_title">hsbljyy 写道</div>
<div class="quote_div">
<div class="quote_title">jinyanhui2008 写道</div>
<div class="quote_div">
<p>在经常需要调用的地方将变量设成全局的甚至是静态的,我的操作是设成全局的了。图省事呢。呵呵,因为我的变量时全局都要调用的而且是频繁调用的。</p>
<p>用完的变量一定要记得让它等于null,否则执行gc()貌似是不给回收的。</p>
</div>
<p><br>不是很明白你这句话中的全局变量指的是什么。如果指的是对象范围内的全局变量,那么在这个对象没有被外部引用的时候,gc应该会处理好这些关系。没有被gc回收的原因肯定是你这个变量指向的对象还存在其他的引用,用static修饰的也一样,除非你用的是static final修饰。</p>
<p> </p>
</div>
<p>    一般来说,全局变量指的就是类的可变属性,也就是你所说的对象范围内的全局变量。同时纠正一点,static的变量是存储在PermGen空间中,而不是heap中(当然了,static变量所引用的对象是会可能在Heap中的),PermGen过大也会超出内存溢出的错误。并且static变量引用的对象属于根引用的序列中,所以即使没有了任何其他引用,一样不会被GC回收,所以你举的这个例子是不对的。</p>
24 楼 凤舞凰扬 2009-09-07  
jinyanhui2008 写道

这个问题,我是在别的网站上看的,所以才这么说的,要调试远程程序,远程使用的jre要用Jrockit的jre才行,具体怎么回事我找不到当时哪个网址了,记不得了。
但是他再生产环境下调试本地程序是没问题的,这是我已经测试过的。
或者我说的堆栈溢出并不准确,我觉得能解决问题才是最大的。

     调试远程程序和使用JRockit没有关系,在JVM的规范中本来就有了JPDA(Java Platform Debug Architecture)。当然了,你还是需要使用某些工具来实现可视化的分析的,但并不只有JRockit而已。
     解决问题自然是关键,但是对于问题的描述和分析,是你解决问题的前提。有些细节会让别人觉得你是否专业,尤其是你想去和别人分享你的经验的时候,请一定注意。
23 楼 jinyanhui2008 2009-09-05  
<div class="quote_title">hsbljyy 写道</div>
<div class="quote_div">
<div class="quote_title">jinyanhui2008 写道</div>
<div class="quote_div">
<div class="quote_title">hsbljyy 写道</div>
<div class="quote_div">
<div class="quote_title">jinyanhui2008 写道</div>
<div class="quote_div">
<p>在经常需要调用的地方将变量设成全局的甚至是静态的,我的操作是设成全局的了。图省事呢。呵呵,因为我的变量时全局都要调用的而且是频繁调用的。</p>
<p>用完的变量一定要记得让它等于null,否则执行gc()貌似是不给回收的。</p>
</div>
<p><br>不是很明白你这句话中的全局变量指的是什么。如果指的是对象范围内的全局变量,那么在这个对象没有被外部引用的时候,gc应该会处理好这些关系。没有被gc回收的原因肯定是你这个变量指向的对象还存在其他的引用,用static修饰的也一样,除非你用的是static final修饰。</p>
<p> </p>
</div>
<p>是啊,太具体的也没有深入研究,肯定是还有其他地方在引用,我也说不上来是为啥,做程序员坐久了有的时候就没时间去深究了,已解决问题为最终目标了。</p>
<p>我说的那段话,因为我开始是每次用用到那个变量或者类的时候都去new一下,而且那个东西可能会频繁的访问,所以造成了资源的很大浪费,所以才写了上面的那段话。</p>
</div>
<p><br>可能会频繁访问?我想知道你说的这个变量是Java的8种基本类型还是类对象,为什么频繁访问,如果是类对象,那么该对象有没有状态?个人感觉你说的还是太泛了,没有说到点上。至于你说的每次使用就new一个对象这种问题,可以参考数据库连接池的设计理念来解决。</p>
</div>
<p><br>是啊。程序设计确实还有很多地方值得我去研究,大多数地方我用了spring去管理了,只有几个类没有用spring来管理,然后就造成溢出了,哈哈不过现在搞好了,抽空真的要看看java设计思想了。。。要不永远只是个码代码的。</p>
22 楼 jinyanhui2008 2009-09-05  
bencode 写道
teasp 写道
jrockit免费的?太好了,这个工具在linux下能用不?

另外,楼主这句“用完的变量一定要记得让它等于null,否则执行gc()貌似是不给回收的”是严重错误的。


看楼主的截图, jrockit是基于eclipse平台开发的RCP程序,肯定可以在linux下使用。
去找找看。应该有linux的下载链接的

对的,他是可以跨平台的。。
21 楼 dong_java 2009-09-05  
不错,谢楼主,能给个下载地址吗?免费破解的。谢了
20 楼 xzh_endless 2009-09-04  
sun 自带的工具里面jmap jhat  可以解决你的问题 。
19 楼 hsbljyy 2009-09-04  
<div class="quote_title">jinyanhui2008 写道</div>
<div class="quote_div">
<div class="quote_title">hsbljyy 写道</div>
<div class="quote_div">
<div class="quote_title">jinyanhui2008 写道</div>
<div class="quote_div">
<p>在经常需要调用的地方将变量设成全局的甚至是静态的,我的操作是设成全局的了。图省事呢。呵呵,因为我的变量时全局都要调用的而且是频繁调用的。</p>
<p>用完的变量一定要记得让它等于null,否则执行gc()貌似是不给回收的。</p>
</div>
<p><br>不是很明白你这句话中的全局变量指的是什么。如果指的是对象范围内的全局变量,那么在这个对象没有被外部引用的时候,gc应该会处理好这些关系。没有被gc回收的原因肯定是你这个变量指向的对象还存在其他的引用,用static修饰的也一样,除非你用的是static final修饰。</p>
<p> </p>
</div>
<p>是啊,太具体的也没有深入研究,肯定是还有其他地方在引用,我也说不上来是为啥,做程序员坐久了有的时候就没时间去深究了,已解决问题为最终目标了。</p>
<p>我说的那段话,因为我开始是每次用用到那个变量或者类的时候都去new一下,而且那个东西可能会频繁的访问,所以造成了资源的很大浪费,所以才写了上面的那段话。</p>
</div>
<p><br>可能会频繁访问?我想知道你说的这个变量是Java的8种基本类型还是类对象,为什么频繁访问,如果是类对象,那么该对象有没有状态?个人感觉你说的还是太泛了,没有说到点上。至于你说的每次使用就new一个对象这种问题,可以参考数据库连接池的设计理念来解决。</p>
18 楼 bencode 2009-09-04  
teasp 写道
jrockit免费的?太好了,这个工具在linux下能用不?

另外,楼主这句“用完的变量一定要记得让它等于null,否则执行gc()貌似是不给回收的”是严重错误的。


看楼主的截图, jrockit是基于eclipse平台开发的RCP程序,肯定可以在linux下使用。
去找找看。应该有linux的下载链接的
17 楼 rwl6813021 2009-09-04  
jrockit确实不错,听说性能比JDK要好65%,特别是在内存处理方面。
不过没敢用在生产环境,感觉不是特别的稳定。
用它来查查问题,运行一些测试程序还是不错的。
16 楼 whaosoft 2009-09-04  
jrockit 看起来挺不错的工具,学习一下
15 楼 Jwind 2009-09-03  
<div class="quote_title">jinyanhui2008 写道</div>
<div class="quote_div">
<div class="quote_title">hsbljyy 写道</div>
<div class="quote_div">
<div class="quote_title">jinyanhui2008 写道</div>
<div class="quote_div">
<p>在经常需要调用的地方将变量设成全局的甚至是静态的,我的操作是设成全局的了。图省事呢。呵呵,因为我的变量时全局都要调用的而且是频繁调用的。</p>
<p><span style="color: #ff0000;">用完的变量一定要记得让它等于null,否则执行gc()貌似是不给回收的。</span></p>
</div>
<p><br>不是很明白你这句话中的全局变量指的是什么。如果指的是对象范围内的全局变量,那么在这个对象没有被外部引用的时候,gc应该会处理好这些关系。没有被gc回收的原因肯定是你这个变量指向的对象还存在其他的引用,用static修饰的也一样,除非你用的是static final修饰。</p>
<p> </p>
</div>
<p>是啊,太具体的也没有深入研究,肯定是还有其他地方在引用,我也说不上来是为啥,做程序员坐久了有的时候就没时间去深究了,已解决问题为最终目标了。</p>
<p>我说的那段话,因为我开始是每次用用到那个变量或者类的时候都去new一下,而且那个东西可能会频繁的访问,所以造成了资源的很大浪费,所以才写了上面的那段话。</p>
</div>
<p> </p>
<p> </p>
<p>“用完的变量一定要记得让它等于null”,你写这句话的时候是否考虑过会给很多人造成误解?</p>
<p> </p>
<p>依稀记得Thinking in Java里面是这样说的,让变量等于null(也就是让这个引用指向null,不在引用这个对象),如果这个对象没有被其他地方使用,JVM就会在适当的时候回收对象。等于null并不回收,执行gc()也并不是说一定进行回收,只是建议垃圾回收机制回收,在Java里是无法人为控制垃圾回收的。</p>
<p> </p>
<p>并不是所有对象不再使用时,就把引用指向null。没有建议这样做,也没有必要这样做。什么时候让一个引用指向null,不是有出栈进栈这个例子吗。</p>
14 楼 jinyanhui2008 2009-09-03  
<div class="quote_title">hsbljyy 写道</div>
<div class="quote_div">
<div class="quote_title">jinyanhui2008 写道</div>
<div class="quote_div">
<p>在经常需要调用的地方将变量设成全局的甚至是静态的,我的操作是设成全局的了。图省事呢。呵呵,因为我的变量时全局都要调用的而且是频繁调用的。</p>
<p>用完的变量一定要记得让它等于null,否则执行gc()貌似是不给回收的。</p>
</div>
<p><br>不是很明白你这句话中的全局变量指的是什么。如果指的是对象范围内的全局变量,那么在这个对象没有被外部引用的时候,gc应该会处理好这些关系。没有被gc回收的原因肯定是你这个变量指向的对象还存在其他的引用,用static修饰的也一样,除非你用的是static final修饰。</p>
<p> </p>
</div>
<p>是啊,太具体的也没有深入研究,肯定是还有其他地方在引用,我也说不上来是为啥,做程序员坐久了有的时候就没时间去深究了,已解决问题为最终目标了。</p>
<p>我说的那段话,因为我开始是每次用用到那个变量或者类的时候都去new一下,而且那个东西可能会频繁的访问,所以造成了资源的很大浪费,所以才写了上面的那段话。</p>
13 楼 hsbljyy 2009-09-03  
<div class="quote_title">jinyanhui2008 写道</div>
<div class="quote_div">
<p>在经常需要调用的地方将变量设成全局的甚至是静态的,我的操作是设成全局的了。图省事呢。呵呵,因为我的变量时全局都要调用的而且是频繁调用的。</p>
<p>用完的变量一定要记得让它等于null,否则执行gc()貌似是不给回收的。</p>
</div>
<p><br>不是很明白你这句话中的全局变量指的是什么。如果指的是对象范围内的全局变量,那么在这个对象没有被外部引用的时候,gc应该会处理好这些关系。没有被gc回收的原因肯定是你这个变量指向的对象还存在其他的引用,用static修饰的也一样,除非你用的是static final修饰。</p>
<p> </p>
12 楼 jinyanhui2008 2009-09-03  
pricecome 写道
死活要安它的jvm怎么办,不安它的jvm好使不?









pricecome.com

主要是你安也要安不安还是要安啊,他的安装程序里面就已经集成了啊。。。
11 楼 pricecome 2009-09-03  
死活要安它的jvm怎么办,不安它的jvm好使不?









http://www.pricecome.com
10 楼 jinyanhui2008 2009-09-03  
teasp 写道
jrockit免费的?太好了,这个工具在linux下能用不?

另外,楼主这句“用完的变量一定要记得让它等于null,否则执行gc()貌似是不给回收的”是严重错误的。

这个概念我还真的是很模糊,因为在调试的时候我发现有些变量new了,然后没有让他置为null,确实是不给回收的,所以才写了那么句话。。。
希望你能给解释一下。。。我不太懂java的内存回收机制。
9 楼 pricecome 2009-09-03  
强 我正在找PROFILE工具

相关推荐

Global site tag (gtag.js) - Google Analytics