﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>BlogJava-cyj86-随笔分类-典型、疑难问题</title><link>http://www.blogjava.net/cyj86/category/48841.html</link><description /><language>zh-cn</language><lastBuildDate>Mon, 13 Jun 2011 03:50:58 GMT</lastBuildDate><pubDate>Mon, 13 Jun 2011 03:50:58 GMT</pubDate><ttl>60</ttl><item><title>Java加载dll，导致Java进程内存泄露</title><link>http://www.blogjava.net/cyj86/archive/2011/06/13/352149.html</link><dc:creator>薛定谔的猫</dc:creator><author>薛定谔的猫</author><pubDate>Mon, 13 Jun 2011 03:45:00 GMT</pubDate><guid>http://www.blogjava.net/cyj86/archive/2011/06/13/352149.html</guid><wfw:comment>http://www.blogjava.net/cyj86/comments/352149.html</wfw:comment><comments>http://www.blogjava.net/cyj86/archive/2011/06/13/352149.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/cyj86/comments/commentRss/352149.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/cyj86/services/trackbacks/352149.html</trackback:ping><description><![CDATA[By zhaoch<br /><br />
<div><span style="line-height: 22px; border-collapse: collapse; font-family: Arial, sans-serif; color: #7b7d72">在做网络监控<span style="border-bottom: #ff0000 1px solid; line-height: normal; word-wrap: break-word; white-space: nowrap; cursor: pointer" href="tag.php?name=%CF%B5%CD%B3">系统</span>的<span style="border-bottom: #ff0000 1px solid; line-height: normal; word-wrap: break-word; white-space: nowrap; cursor: pointer" href="tag.php?name=%D0%D4%C4%DC%B2%E2%CA%D4"><span style="border-bottom: #ff0000 1px solid; line-height: normal; word-wrap: break-word; white-space: nowrap; cursor: pointer" href="tag.php?name=%D0%D4%C4%DC">性能</span>测试</span>时，出现了<span style="border-bottom: #ff0000 1px solid; line-height: normal; word-wrap: break-word; white-space: nowrap; cursor: pointer" href="tag.php?name=%C4%DA%B4%E6">内存</span>泄露的问题，困扰了很久，现在终于算是解决了，但是根本原因尚不明确，拿出来大家讨论下，看看能不能完美解决～<br style="line-height: normal; word-wrap: break-word" /><br style="line-height: normal; word-wrap: break-word" />这个问题奇怪的地方在于是<span style="border-bottom: #ff0000 1px solid; line-height: normal; word-wrap: break-word; white-space: nowrap; cursor: pointer" href="tag.php?name=Java">Java</span>进程内存泄露，而不是平常的JVM内存泄露，用Jprofile等<span style="border-bottom: #ff0000 1px solid; line-height: normal; word-wrap: break-word; white-space: nowrap; cursor: pointer" href="tag.php?name=%B9%A4%BE%DF">工具</span>也无法看出问题所在。<br style="line-height: normal; word-wrap: break-word" /><br style="line-height: normal; word-wrap: break-word" />测试<span style="border-bottom: #ff0000 1px solid; line-height: normal; word-wrap: break-word; white-space: nowrap; cursor: pointer" href="tag.php?name=%B4%FA%C2%EB">代码</span>如下：<br /><br />
<div style="border-bottom: #cccccc 1px solid; border-left: #cccccc 1px solid; padding-bottom: 4px; background-color: #eeeeee; padding-left: 4px; width: 98%; padding-right: 5px; font-size: 13px; word-break: break-all; border-top: #cccccc 1px solid; border-right: #cccccc 1px solid; padding-top: 4px"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><span style="color: #008080">&nbsp;1</span>&nbsp;<span style="color: #000000">System.loadLibrary(</span><span style="color: #000000">"</span><span style="color: #000000">test1</span><span style="color: #000000">"</span><span style="color: #000000">);<br /></span><span style="color: #008080">&nbsp;2</span>&nbsp;<span style="color: #000000"><br /></span><span style="color: #008080">&nbsp;3</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">int</span><span style="color: #000000">&nbsp;threadPoolSize&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">400</span><span style="color: #000000">;<br /></span><span style="color: #008080">&nbsp;4</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ExecutorService&nbsp;service&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;Executors.newFixedThreadPool(threadPoolSize);<br /></span><span style="color: #008080">&nbsp;5</span>&nbsp;<span style="color: #000000"><br /></span><span style="color: #008080">&nbsp;6</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">for</span><span style="color: #000000">&nbsp;(</span><span style="color: #0000ff">int</span><span style="color: #000000">&nbsp;i&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">0</span><span style="color: #000000">;&nbsp;i&nbsp;</span><span style="color: #000000">&lt;</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">400</span><span style="color: #000000">;&nbsp;i</span><span style="color: #000000">++</span><span style="color: #000000">)&nbsp;{<br /></span><span style="color: #008080">&nbsp;7</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;service.submit(</span><span style="color: #0000ff">new</span><span style="color: #000000">&nbsp;Runnable()&nbsp;{<br /></span><span style="color: #008080">&nbsp;8</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">public</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">void</span><span style="color: #000000">&nbsp;run()&nbsp;{<br /></span><span style="color: #008080">&nbsp;9</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">while</span><span style="color: #000000">&nbsp;(</span><span style="color: #0000ff">true</span><span style="color: #000000">)&nbsp;{<br /></span><span style="color: #008080">10</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">try</span><span style="color: #000000">&nbsp;{<br /></span><span style="color: #008080">11</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Thread&nbsp;t&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">new</span><span style="color: #000000">&nbsp;Thread();<br /></span><span style="color: #008080">12</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;t.start();<br /></span><span style="color: #008080">13</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Thread.sleep(</span><span style="color: #000000">100</span><span style="color: #000000">);<br /></span><span style="color: #008080">14</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;</span><span style="color: #0000ff">catch</span><span style="color: #000000">&nbsp;(Exception&nbsp;e)&nbsp;{<br /></span><span style="color: #008080">15</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;e.printStackTrace();<br /></span><span style="color: #008080">16</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br /></span><span style="color: #008080">17</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br /></span><span style="color: #008080">18</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br /></span><span style="color: #008080">19</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;});<br /></span><span style="color: #008080">20</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</span></div></span></div><br />
<div style="display: inline-block">
<div></div></div><span style="line-height: 22px; border-collapse: collapse; font-family: Arial, sans-serif; color: #7b7d72" class="Apple-style-span">说明：此段代码所做的工作就是加载一个dll，然后不断的启动线程（线程什么也不做，直接终止）。<br style="line-height: normal; word-wrap: break-word" />注：线程池只是为了加速问题复现，无其他用处。<br style="line-height: normal; word-wrap: break-word" /><br style="line-height: normal; word-wrap: break-word" />现象：<br style="line-height: normal; word-wrap: break-word" />1.如果不加载dll，只不断的启动线程，Java进程内存正常，不会一直增长。<br style="line-height: normal; word-wrap: break-word" />2.如果加载附件中test1的dll，Java进程内存会一直增长。<br style="line-height: normal; word-wrap: break-word" />3.如果加载附件中test2的dll（需要安装C++运行环境vcredist_x86），Java进程内存正常，不会一直增长。<br style="line-height: normal; word-wrap: break-word" /><br style="line-height: normal; word-wrap: break-word" />dll说明：<br style="line-height: normal; word-wrap: break-word" />dll的工程源码在附件中，test1和test2的区别只在于编译选项，如附件：test1选择的是&#8220;使用标准<span style="border-bottom: #ff0000 1px solid; line-height: normal; word-wrap: break-word; white-space: nowrap; cursor: pointer" href="tag.php?name=Windows">Windows</span>库&#8221;或&#8220;在静态库中使用MFC&#8221;，test2选择的是&#8220;在共享DLL中使用MFC&#8221;<br style="line-height: normal; word-wrap: break-word" />此dll工程的特点在于使用了jni，并引入了mfc头<span style="border-bottom: #ff0000 1px solid; line-height: normal; word-wrap: break-word; white-space: nowrap; cursor: pointer" href="tag.php?name=%CE%C4%BC%FE">文件</span>【#include &lt;afxwin.h&gt;】，如果不引入mfc头文件则不会引起内存泄漏<br style="line-height: normal; word-wrap: break-word" /><br style="line-height: normal; word-wrap: break-word" /><br style="line-height: normal; word-wrap: break-word" />目前此问题的根本原因尚不明确，怀疑是jdk的<span style="border-bottom: #ff0000 1px solid; line-height: normal; word-wrap: break-word; white-space: nowrap; cursor: pointer" href="tag.php?name=bug">bug</span>（使用最新的jdk1.6.0.23也没用），不知道大家有什么想法吗？欢迎大家讨论～<br /><br /><a href="/Files/cyj86/dll工程.rar">/Files/cyj86/dll工程.rar</a><br /><a href="/Files/cyj86/test1.rar">/Files/cyj86/test1.rar</a><br /><a href="/Files/cyj86/test2.rar">/Files/cyj86/test2.rar</a><br /><a href="/Files/cyj86/vcredist_x86.rar">/Files/cyj86/vcredist_x86.rar</a><br /><a href="/Files/cyj86/opt.png">/Files/cyj86/opt.png</a><img border="0" alt="" src="http://www.blogjava.net/images/blogjava_net/cyj86/opt.png" width="746" longdesc="" height="545" /><br /></span> <img src ="http://www.blogjava.net/cyj86/aggbug/352149.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/cyj86/" target="_blank">薛定谔的猫</a> 2011-06-13 11:45 <a href="http://www.blogjava.net/cyj86/archive/2011/06/13/352149.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>