http://liyanblog.cn/李岩的博客 李岩 java lucene 搜索 nosql hadoop 博客 mongodb, java2024-03-29T17:18:59+08:00李岩的博客NoSuchFieldError: INSTANCE 异常是因为jar冲突。仔细检查jar是否有重复。savagertnullhttp://liyanblog.cn/articles/2019/09/20/1568964006209.html2019-09-20T15:20:06+08:00<p>org.springframework.beans.factory.BeanDefinitionStoreException: Unexpected exception parsing XML document from ServletContext resource [/WEB-INF/spring/applicationContext-sca.xml]; nest<br />ed exception is java.lang.NoSuchFieldError: INSTANCE<br /> at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.doLoadBeanDefinitions(XmlBeanDefinitionReader.java:419)</p>java 内存泄漏查找savagertnullhttp://liyanblog.cn/articles/2019/08/20/1566286414148.html2019-08-20T15:33:34+08:00<p>内存泄漏查找<br />先ps出java的进程号pid<br /><br />jstat -gcutil pid 1000<br />意思是每1000毫秒查询一次,一直查。gcutil的意思是已使用空间站总空间的百分比。<br /> <br />jstat执行结果<br /><br />查询结果表明:这台服务器的新生代Eden区(E,表示Eden)使用了28.30%(最后)的空间,两个Survivor区(S0、S1,表示Survivor0、Survivor1)分别是0和8.93%,老年代(O,表示Old)使用了87.33%。程序运行以来共发生Minor GC(YGC,表示Young GC)101次,总耗时1.961秒,发生Full GC(FGC,表示Full GC)7次,Full GC总耗时3.022秒,总的耗时(GCT,表示GC Time)为4.983秒。<br /> <br /><br />使用“Java内存影像工具:jmap”生成堆转储快照(一般称为headdump或dump文件)。<br />jmap命令格式:<br />jmap [ option ] vmid<br />使用命令如下:<br />jmap -histo:live 20954<br />jmap -histo:live 20954<br /><br /><br />定位到代码<br /><br />定位带代码,有很多种方法,比如前面提到的通过MAT查看Histogram即可找出是哪块代码<br />Java的内存泄露多半是因为对象存在无效的引用,对象得不到释放,如果发现Java应用程序占用的内存出现了泄露的迹象,那么我们一般采用下面的步骤分析:<br />1. 用工具生成java应用程序的heap dump(如jmap)<br />2. 使用Java heap分析工具(如MAT),找出内存占用超出预期的嫌疑对象<br />3. 根据情况,分析嫌疑对象和其他对象的引用关系。<br />4. 分析程序的源代码,找出嫌疑对象数量过多的原因。<br /> 以下一步步的按照项目实例来操作,去解决内存泄露的问题。<br /><br />1. 登录linux服务器,获取tomcat的pid,命令:<br /><br />[html] view plain copy<br /><br /> ps -ef|grep java <br /><br /><br /><br />2. 利用jmap初步分析内存映射,命令:<br /><br />[html] view plain copy<br /><br /> jmap -histo:live 3514 | head -7 <br /><br /><br />第2行是我们业务系统的对象,通过这个对象的引用可以初步分析出到底是哪里出现了引用未被垃圾回收收集,通知开发人员优化相关代码。<br /><br /><br />3. 如果上面一步还无法定位到关键信息,那么需要拿到heap dump,生成离线文件,做进一步分析,命令:<br /><br />[html] view plain copy<br /><br /> jmap -dump:live,format=b,file=heap.hprof 3514 <br /><br /><br /><br />4. 拿到heap dump文件,利用eclipse插件MAT来分析heap profile。<br /><br />a. 安装MAT插件<br /><br />b. 在eclipse里切换到Memory Analysis视图<br /><br />c. 用MAT打开heap profile文件。<br /><br /><br />Memory Analyzer插件下载<br /><br />直接看到下面Action窗口,有4种Action来分析heap profile,介绍其中最常用的2种:<br /><br />- Histogram:这个使用的最多,跟上面的jmap -histo 命令类似,只是在MAT里面可以用GUI来展示应用系统各个类产生的实例。<br /><br /><br />Shllow Heap排序后发现 Cms_Organization 这个类占用的内存比较多(没有得到及时GC),查看引用:<br /><br /><br />分析引用栈,找到无效引用,打开源码:<br /><br /><br /> https://blog.csdn.net/fishinhouse/article/details/80781673</p>eclipse 应用YourKit 在运行里加入这个参数savagertnullhttp://liyanblog.cn/articles/2019/07/11/1562813296395.html2019-07-11T10:48:16+08:00<p>前提在本地安装好软件。</p>
<p>-agentpath:"C:\Program Files (x86)\YourKit Java Profiler 9.0.3\bin\win32\yjpagent.dll=disablestacktelemetry,disableexceptiontelemetry,builtinprobes=none,delay=10000"</p>tomcat每个10秒回收一次内存问题解决savagertnullhttp://liyanblog.cn/articles/2019/06/18/1560851345051.html2019-06-18T17:49:05+08:00<p>用yourkit,监控tomcat启动,然后发现只有一个Thread()方法占用大量的cpu。但是却无法展开,于是查看stack页。发现有一个占用98%的时间。名称叫做ContainerBackgroundProcessor[StandardEngine[Catalina]]]</p>
<p>于是百度这个。发现一篇文章。将tomcat源码多,发现问题是tomcat开启了热启动,每个10秒。扫描下class有没有改变。于是造成大量的内存出现,从而激发的GC。操作cup占用率高。</p>
<p>https://yq.aliyun.com/articles/20172</p>
<p> </p>
<p>修改server.xml文件中的 reloadable="true" 为 reloadable="false" </p>
<p><Host 。。。。。 ></p>
<p><Context displayName="Welcome to Tomcat" docBase="D:/Tomcat/apache-tomcat-8.5.42/abc" path="" reloadable="false" ></Context></p>
<p></Host></p>eclipse安装Eclipse HTML Editor插件savagertnullhttp://liyanblog.cn/articles/2016/09/15/1473901482343.html2016-09-15T09:04:42+08:00<p>需插件:<br /> <br /> 1、GEF 3.1 安装程序下载<br /> <br /> 下载地址:<br /> <br /> http://download.eclipse.org/tools/gef/downloads/drops/R-3.1-200507071758/index.php<br /> <br /> 这里我们下载GEF-ALL-3.1.zip。<br /> <br /> 2、Eclipse HTML Editor 1.6.7 安装程序下载<br /> <br /> 下载地址:https://sourceforge.jp/projects/amateras/files/?release_id=16537#16537<br /> <br /> 这里我们下载:tk.eclipse.plugin.htmleditor_1.6.7.zip。<br /> <br /> 安装步骤:<br /> <br /> 1、安装GEF插件<br /> <br /> 同样,将GEF-ALL-3.1.zip解压缩,然后拷贝解压后的eclipse目录下的三个文件夹到D:\eclipse目录下,覆盖所有的现有文件夹。<br /> <br /> 好了,到此GEF安装完成。<br /> <br /> 2、安装Eclipse HTML Editor插件<br /> <br /> 解压缩tk.eclipse.plugin.htmleditor_1.6.7.zip包,然后将plugins目录拷贝至D:\eclipse目录下覆盖原文件夹即可。到此Eclipse HTML Editor插件安装完成。<br /> <br /> 完成以上步骤,打开Eclipse,file——〉new——〉other——〉Amateras即可看见其功能。</p>Full gc 每小时被自动执行一次 禁止方法savagertnullhttp://liyanblog.cn/articles/2016/09/09/1473410638692.html2016-09-09T16:43:58+08:00<p>近日开始关注JVM的问题,先用jstat -gcutil pid随意看了一套web系统的JVM情况(容器是tomcat 7,jdk是1.7),结果非常惊讶,Full GC频繁,且周期性出现。大概每小时一次。</p>
<p> </p>
<p> 问题出现了,好兴奋啊,搞定它我就能增长经验了哇!!于是乎,和我们亲爱的SA同事交流了一番,我用nohup jstat -gccause pid 1s >> ~/xxx/xxx.log &先把gccause日志记录下来,经过半天日志记录追踪之后,发现LGCC是System.gc()。很好奇怎么会出现这东西,我写的代码肯定 没有System.gc(),有点怀疑是tomcat的问题(当时也只是怀疑,无任何根据的)。为了解决这个问题,我先尝试在JVM启动参数中加入 -XX:+DisableExplicitGC来禁止System.gc(),大半天后再用jstat看gc情况,FGC的次数是0,然后问题解决了。</p>
<p> </p>
<p> 虽然问题临时解决了,为了知其然知其所以然,我继续深究了一番,最终找到了问题所在:是tomcat 7的一个默认配置(JreMemoryLeakPreventionListener)所导致的,更合适的解决方法似乎是 <Listener className="org.apache.catalina.core.JreMemoryLeakPreventionListener" gcDaemonProtection="false"/>。</p>Full gc时间长如何调节jvmsavagertnullhttp://liyanblog.cn/articles/2015/10/02/1443783708871.html2015-10-02T19:01:48+08:00<p style="padding-left: 30px;" align="left">下面这个例子针对 <strong>Service S</strong>的优化,对于最近被部署的 Service S,Full GC花费了太长的时间。</p>
<p style="padding-left: 30px;" align="left">请看 jstat –gcutil的执行结果。</p>
<div>
<div id="highlighter_677525" class="syntaxhighlighter notranslate actionscript3">
<table border="0" cellspacing="0" cellpadding="0">
<tbody>
<tr>
<td class="gutter">
<div class="line number1 index0 alt2">1</div>
<div class="line number2 index1 alt1">2</div>
</td>
<td class="code">
<div class="container">
<div class="line number1 index0 alt2"><code class="actionscript3 plain">S0 S1 E O P YGC YGCT FGC FGCT GCT</code></div>
<div class="line number2 index1 alt1"><code class="actionscript3 value">12.16</code> <code class="actionscript3 value">0.00</code> <code class="actionscript3 value">5.18</code> <code class="actionscript3 value">63.78</code> <code class="actionscript3 value">20.32</code> <code class="actionscript3 value">54</code> <code class="actionscript3 value">2.047</code> <code class="actionscript3 value">5</code> <code class="actionscript3 value">6.946</code> <code class="actionscript3 value">8.993</code></div>
</div>
</td>
</tr>
</tbody>
</table>
</div>
</div>
<p style="padding-left: 30px;" align="left">最左边的<strong>Perm</strong> 空间对于最初的GC优化不是很重要,这一次YGC参数的值更加有用。</p>
<p style="padding-left: 30px;" align="left">Minor GC和Full GC的平均值如下表所示</p>
<p align="center"><strong>表</strong><strong>3</strong><strong>:</strong><strong>Service S</strong><strong>的</strong><strong>Minor GC </strong><strong>和</strong><strong>Full GC</strong><strong>的平均执行时间</strong></p>
<table width="550" border="1" cellspacing="0" cellpadding="0">
<thead>
<tr>
<td>
<p align="left">GC 类型</p>
</td>
<td width="150">
<p align="left">GC 执行次数</p>
</td>
<td width="161">
<p align="left">GC 执行时间</p>
</td>
<td width="150">
<p align="left">平均</p>
</td>
</tr>
</thead>
<tbody>
<tr>
<td>
<p align="left">Minor GC</p>
</td>
<td width="150">
<p align="left">54</p>
</td>
<td width="161">
<p align="left">2.047</p>
</td>
<td width="150">
<p align="left">37 ms</p>
</td>
</tr>
<tr>
<td>
<p align="left">Full GC</p>
</td>
<td width="150">
<p align="left">5</p>
</td>
<td width="161">
<p align="left">6.946</p>
</td>
<td width="150">
<p align="left">1,389 s</p>
</td>
</tr>
</tbody>
</table>
<p style="padding-left: 30px;" align="left">最重要的是下面两个数据</p>
<ul>
<li>新生代实际使用空间: 212,992 KB</li>
<li>老年代实际使用空间: 1,884,160 KB</li>
</ul>
<p style="padding-left: 30px;" align="left">因此,总的内存空间为2GB,不算Perm空间的话,新生代与老年代之比为1:9。通过<strong>jstat</strong>和-verbosegc 日志进行数据收集,并把三台服务器按照如下方式设置。</p>
<ul>
<li>NewRatio=2</li>
<li>NewRatio=3</li>
<li>NewRatio=4</li>
</ul>
<p style="padding-left: 30px;" align="left">一天之后,检查系统的GC日志后发现,在设置了NewRatio参数后很幸运的没有发生Full GC,</p>
<p style="padding-left: 30px;" align="left"><strong>为什么?</strong></p>
<ul>
<li>NewRatio=2: 45 ms</li>
<li>NewRatio=3: 34 ms</li>
<li>NewRatio=4: 30 ms</li>
</ul>
<p style="padding-left: 30px;" align="left">我们看到NewRatio=4 是最佳的参数,虽然它的新生代空间最小,但GC时间确最短。设定这个参数之后,系统没有执行过Full GC。</p>
<p style="padding-left: 30px;" align="left">为了说明这个问题,下面是服务之星一段时间后执行jstat –gcutil的结果</p>
<div style="padding-left: 30px;">
<div>
<div id="highlighter_485625" class="syntaxhighlighter notranslate actionscript3">
<table border="0" cellspacing="0" cellpadding="0">
<tbody>
<tr>
<td class="gutter">
<div class="line number1 index0 alt2">1</div>
<div class="line number2 index1 alt1">2</div>
</td>
<td class="code">
<div class="container">
<div class="line number1 index0 alt2"><code class="actionscript3 plain">S0 S1 E O P YGC YGCT FGC FGCT GCT</code></div>
<div class="line number2 index1 alt1"><code class="actionscript3 value">8.61</code> <code class="actionscript3 value">0.00</code> <code class="actionscript3 value">30.67</code> <code class="actionscript3 value">24.62</code> <code class="actionscript3 value">22.38</code> <code class="actionscript3 value">2424</code> <code class="actionscript3 value">30.219</code> <code class="actionscript3 value">0</code> <code class="actionscript3 value">0.000</code> <code class="actionscript3 value">30.219</code></div>
</div>
</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
<p style="padding-left: 30px;" align="left">你可能会认为因为服务器接受的请求少才导致的GC执行频率下降。实际上,虽然Full GC没有执行,但是Minor GC被执行了 2,424次。</p>urlrewrite url匹配?问号之后的内容。savagertnullhttp://liyanblog.cn/articles/2015/07/16/1437032198948.html2015-07-16T15:36:39+08:00<div id="blog_content" class="blog_content">
<p> </p>
<div style="border: 1px solid #cccccc; padding: 4px 5px 4px 4px; font-size: 13px; width: 98%; background-color: #eeeeee;"><span style="color: #000000;"> </span> <span style="color: #0000ff;"><</span> <span style="color: #800000;">rule</span> <span style="color: #0000ff;">></span> <span style="color: #000000;"><br /> </span> <span style="color: #0000ff;"><</span> <span style="color: #800000;">from</span> <span style="color: #0000ff;">></span> <span style="color: #000000;">^/article.asp\?id=(.*)$</span> <span style="color: #0000ff;"></</span> <span style="color: #800000;">from</span> <span style="color: #0000ff;">></span> <span style="color: #000000;"><br /> </span> <span style="color: #0000ff;"><</span> <span style="color: #800000;">to </span> <span style="color: #ff0000;">type</span> <span style="color: #0000ff;">="redirect"</span> <span style="color: #0000ff;">></span> <span style="color: #000000;">/entry/$1.jhtml</span> <span style="color: #0000ff;"></</span> <span style="color: #800000;">to</span> <span style="color: #0000ff;">></span> <span style="color: #000000;"><br /> </span> <span style="color: #0000ff;"></</span> <span style="color: #800000;">rule</span> <span style="color: #0000ff;">></span></div>
<p> 但是我这样的连接总是匹配不到,只要去掉那个?就可以了。这个正则表达式是没有问题的。/article.asp?id=64是可以匹配的到的。<br /> 后来看3.0的manual (http://tuckey.org/urlrewrite/manual/3.0/)才发现原来是这个的问题。</p>
<h3><urlrewrite> element</h3>
<p>The top level element.</p>
Attribute Possible Value Explanation
<table border="0" cellspacing="0">
<tbody>
<tr>
<td>default-match-type <br /><small>(optional)</small></td>
<td><strong>regex</strong> (default)</td>
<td>All rules and thier conditions will be processed using the Java Regular Expression engine (unless <code>match-type</code> is specified on a rule).</td>
</tr>
<tr>
<td>wildcard</td>
<td>All rules and thier conditions will be processed using the <a href="http://tuckey.org/urlrewrite/manual/3.0/#wildcard">Wildcard Expression engine</a> (unless <code>match-type</code> is specified on a rule).</td>
</tr>
<tr>
<td>decode-using <br /><small>(optional)</small></td>
<td><strong>utf8</strong> (default)</td>
<td>When URL is decoded UTF-8 will be used.</td>
</tr>
<tr>
<td>null</td>
<td>Do not decode.</td>
</tr>
<tr>
<td>[encoding]</td>
<td>Any string representing a supported character encoding eg, ISO-8859-1. See <a href="http://java.sun.com/j2se/1.4.2/docs/api/java/nio/charset/Charset.html">Java Charset Object</a> for more info.</td>
</tr>
<tr>
<td style="font-weight: bold; color: #0000ff;">use-query-string <br /><small>(optional)</small></td>
<td><strong>false</strong> (default)</td>
<td>The query string will <em>not</em> be appended to the url that the "from" element matches against.</td>
</tr>
<tr>
<td>true</td>
<td>The query string will be appended to the url that the "from" element matches against.</td>
</tr>
<tr>
<td>use-context <br /><small>(optional)</small></td>
<td><strong>false</strong> (default)</td>
<td>The context path will <em>not</em> be added to the url that the "from" element matches against.</td>
</tr>
<tr>
<td>true</td>
<td>The context path will be added to the url that the "from" element matches against.</td>
</tr>
</tbody>
</table>
<p><br /> 就是那个use-query-string 的问题,默认的是不使用query-string就是把?后面的都忽略了。所以就不能匹配到了。只要在<urlrewrite>里面加一个属性就可以了。</p>
<div style="border: 1px solid #cccccc; padding: 4px 5px 4px 4px; font-size: 13px; width: 98%; background-color: #eeeeee;"><span style="color: #0000ff;"><</span> <span style="color: #800000;">urlrewrite </span> <span style="color: #ff0000;">use-query-string</span> <span style="color: #0000ff;">="true"</span> <span style="color: #0000ff;">></span> <span style="color: #000000;"><br /> <img src="http://www.blogjava.net/images/dot.gif" alt="" /><br /></span> <span style="color: #0000ff;"></</span> <span style="color: #800000;">urlrewrite</span> <span style="color: #0000ff;">></span></div>
</div>url匹配?问号之后的内容。savagertnullhttp://liyanblog.cn/articles/2015/07/16/1437028120699.html2015-07-16T14:28:40+08:00<div id="blog_content" class="blog_content">
<p> </p>
<div style="border: 1px solid #cccccc; padding: 4px 5px 4px 4px; font-size: 13px; width: 98%; background-color: #eeeeee;"><span style="color: #000000;"> </span> <span style="color: #0000ff;"><</span> <span style="color: #800000;">rule</span> <span style="color: #0000ff;">></span> <span style="color: #000000;"><br /> </span> <span style="color: #0000ff;"><</span> <span style="color: #800000;">from</span> <span style="color: #0000ff;">></span> <span style="color: #000000;">^/article.asp\?id=(.*)$</span> <span style="color: #0000ff;"></</span> <span style="color: #800000;">from</span> <span style="color: #0000ff;">></span> <span style="color: #000000;"><br /> </span> <span style="color: #0000ff;"><</span> <span style="color: #800000;">to </span> <span style="color: #ff0000;">type</span> <span style="color: #0000ff;">="redirect"</span> <span style="color: #0000ff;">></span> <span style="color: #000000;">/entry/$1.jhtml</span> <span style="color: #0000ff;"></</span> <span style="color: #800000;">to</span> <span style="color: #0000ff;">></span> <span style="color: #000000;"><br /> </span> <span style="color: #0000ff;"></</span> <span style="color: #800000;">rule</span> <span style="color: #0000ff;">></span></div>
<p> 但是我这样的连接总是匹配不到,只要去掉那个?就可以了。这个正则表达式是没有问题的。/article.asp?id=64是可以匹配的到的。<br /> 后来看3.0的manual (http://tuckey.org/urlrewrite/manual/3.0/)才发现原来是这个的问题。</p>
<h3><urlrewrite> element</h3>
<p>The top level element.</p>
Attribute Possible Value Explanation
<table border="0" cellspacing="0">
<tbody>
<tr>
<td>default-match-type <br /><small>(optional)</small></td>
<td><strong>regex</strong> (default)</td>
<td>All rules and thier conditions will be processed using the Java Regular Expression engine (unless <code>match-type</code> is specified on a rule).</td>
</tr>
<tr>
<td>wildcard</td>
<td>All rules and thier conditions will be processed using the <a href="http://tuckey.org/urlrewrite/manual/3.0/#wildcard">Wildcard Expression engine</a> (unless <code>match-type</code> is specified on a rule).</td>
</tr>
<tr>
<td>decode-using <br /><small>(optional)</small></td>
<td><strong>utf8</strong> (default)</td>
<td>When URL is decoded UTF-8 will be used.</td>
</tr>
<tr>
<td>null</td>
<td>Do not decode.</td>
</tr>
<tr>
<td>[encoding]</td>
<td>Any string representing a supported character encoding eg, ISO-8859-1. See <a href="http://java.sun.com/j2se/1.4.2/docs/api/java/nio/charset/Charset.html">Java Charset Object</a> for more info.</td>
</tr>
<tr>
<td style="font-weight: bold; color: #0000ff;">use-query-string <br /><small>(optional)</small></td>
<td><strong>false</strong> (default)</td>
<td>The query string will <em>not</em> be appended to the url that the "from" element matches against.</td>
</tr>
<tr>
<td>true</td>
<td>The query string will be appended to the url that the "from" element matches against.</td>
</tr>
<tr>
<td>use-context <br /><small>(optional)</small></td>
<td><strong>false</strong> (default)</td>
<td>The context path will <em>not</em> be added to the url that the "from" element matches against.</td>
</tr>
<tr>
<td>true</td>
<td>The context path will be added to the url that the "from" element matches against.</td>
</tr>
</tbody>
</table>
<p><br /> 就是那个use-query-string 的问题,默认的是不使用query-string就是把?后面的都忽略了。所以就不能匹配到了。只要在<urlrewrite>里面加一个属性就可以了。</p>
<div style="border: 1px solid #cccccc; padding: 4px 5px 4px 4px; font-size: 13px; width: 98%; background-color: #eeeeee;"><span style="color: #0000ff;"><</span> <span style="color: #800000;">urlrewrite </span> <span style="color: #ff0000;">use-query-string</span> <span style="color: #0000ff;">="true"</span> <span style="color: #0000ff;">></span> <span style="color: #000000;"><br /> <img src="http://www.blogjava.net/images/dot.gif" alt="" /><br /></span> <span style="color: #0000ff;"></</span> <span style="color: #800000;">urlrewrite</span> <span style="color: #0000ff;">></span></div>
</div>