📄 lib0124.html
字号:
-Xrunhprof:heap=sites,file=mem.hprof.txt,depth=24,cutoff=0.01
</pre>
</div>
<p class="para">Memory leaks are among the most difficult bugs to find and diagnose. The largest objects that can cause memory leaks are statically defined variables, particularly statically defined collections. HPROF provides a trace ranking that details the traces that have the most memory allocated. <a class="internaljump" href="#ch19list05">Listing 19.5</a> is a sample of a memory trace ranking.</p>
<div class="example">
<span class="example-title"><span class="example-titlelabel">Listing 19.5: </span>Sample Memory Trace Ranking</span><a name="619"></a><a name="ch19list05"></a>
<div class="formalbody">
<table class="BlueLine" border="0" cellspacing="0" cellpadding="0" width="100%">
<tr>
<td bgcolor="000080" class="bluecell"><font size="2" face="Arial" color="010100"><b><img src="_.gif" width="1" height="2" alt="Start example" border="0"></b></font></td>
</tr>
</table>
<pre class="literallayout">
SITES BEGIN (ordered by live bytes) Sun Jul 13 11:12:39 2003
percent live alloc'ed stack class
rank self accum bytes objs bytes objs trace name
1 35.21% 35.21% 158256 3297 33600000 700000 419
java.lang.reflect.Field
2 17.42% 52.64% 78312 492 79680 517 1 [C
3 10.10% 62.74% 45416 214 45416 214 1 [B
4 5.03% 67.77% 22608 471 4800000 100000 415
book.sample.dto.cementj.CustomerDTO
5 4.19% 71.96% 18840 471 4000000 100000 418
java.lang.reflect.Field
6 3.91% 75.87% 17576 315 17576 315 1 java.lang.Object
7 3.35% 79.22% 15064 282 15064 282 1 [S
8 2.98% 82.20% 13384 239 13384 239 1 java.lang.Class
9 2.89% 85.09% 12984 541 13632 568 1 java.lang.String
10 2.48% 87.58% 11168 208 601448 220 1 [I
SITES END
</pre>
<table class="BlueLine" border="0" cellspacing="0" cellpadding="0" width="100%">
<tr>
<td bgcolor="000080" class="bluecell"><font size="2" face="Arial" color="010100"><b><img src="_.gif" width="1" height="2" alt="End example" border="0"></b></font></td>
</tr>
</table>
<table class="BlankSpace" border="0" cellspacing="0" cellpadding="0" width="100%">
<tr>
<td height="16"></td>
</tr>
</table>
</div>
</div>
<p class="para">The first aspect of the memory ranking to look at is the ratio of "live" bytes to "allocated" bytes. Live bytes represent memory that is referenceable and currently being used by the application. Allocated bytes represent the total memory allocated within the JVM. The difference between the allocated and live bytes will be garbage collected at some point.</p>
<p class="para">Memory leaks tend to be traces where the live bytes represent close to 100 percent of the allocated bytes. The first trace in <a class="internaljump" href="#ch19list05">listing 19.5</a> doesn't fit this profile, but the second one does. It's important to remember that a high <a name="620"></a><a name="IDX-261"></a>live-to-allocated bytes ratio could indicate a leak, but it's possible to have a high ratio without a leak.</p>
<p class="para">Take a closer look at trace 419, shown in <a class="internaljump" href="#ch19list06">listing 19.6</a>. As the largest memory consumer, trace 419 might be a good place to find something you can tune. The next largest memory consumer, trace 1, might be a place to see a memory leak.</p>
<div class="example">
<span class="example-title"><span class="example-titlelabel">Listing 19.6: </span>Trace 419 from the Sample in Listing 19.5</span><a name="621"></a><a name="ch19list06"></a>
<div class="formalbody">
<table class="BlueLine" border="0" cellspacing="0" cellpadding="0" width="100%">
<tr>
<td bgcolor="000080" class="bluecell"><font size="2" face="Arial" color="010100"><b><img src="_.gif" width="1" height="2" alt="Start example" border="0"></b></font></td>
</tr>
</table>
<pre class="literallayout">
TRACE 419:
java.lang.reflect.Field.copy(Field.java:83)
java.lang.reflect.ReflectAccess.copyField(ReflectAccess.java:9)
sun.reflect.ReflectionFactory.copyField(ReflectionFactory.java:
277)
java.lang.Class.copyFields(Class.java:1962)
java.lang.Class.getDeclaredFields(Class.java:1090)
org.cementj.base.ValueObject.<init>(ValueObject.java:26)
book.sample.dto.cementj.CustomerDTO.<init>(CustomerDTO.java:8)
book.sample.dto.cementj.TestCustomerDTO.main(
TestCustomerDTO.java:38)
</pre>
<table class="BlueLine" border="0" cellspacing="0" cellpadding="0" width="100%">
<tr>
<td bgcolor="000080" class="bluecell"><font size="2" face="Arial" color="010100"><b><img src="_.gif" width="1" height="2" alt="End example" border="0"></b></font></td>
</tr>
</table>
<table class="BlankSpace" border="0" cellspacing="0" cellpadding="0" width="100%">
<tr>
<td height="16"></td>
</tr>
</table>
</div>
</div>
<p class="para">Although you might not recognize the object type consuming the memory, it's important to look at the stack trace because it indicates the code that's allocating the memory. The trace behind trace 419, which is allocating about 35.21 percent of live memory, is presented in <a class="internaljump" href="#ch19list06">listing 19.6</a>.</p>
<p class="para">Once again, look at the first object in the trace that comes from the application. It appears that memory is being allocated from within the constructor of <span class="fixed">ValueObject</span> on line 26. In <a class="internaljump" href="#ch19list07">listing 19.7</a>, line 3 shows the code in <span class="fixed">ValueObject</span> allocating the memory that is highlighted in the trace.</p>
<div class="example">
<span class="example-title"><span class="example-titlelabel">Listing 19.7: </span>Code Highlighted in the Trace</span><a name="622"></a><a name="ch19list07"></a>
<div class="formalbody">
<table class="BlueLine" border="0" cellspacing="0" cellpadding="0" width="100%">
<tr>
<td bgcolor="000080" class="bluecell"><font size="2" face="Arial" color="010100"><b><img src="_.gif" width="1" height="2" alt="Start example" border="0"></b></font></td>
</tr>
</table>
<pre class="literallayout">
1:protected ValueObject()
2: {
3: _classField = this.getClass().getDeclaredFields();
4: for (int i = 0 ; _classField != null &&
5: i < _classField.length; i++)
6: {
7: _classField[i].setAccessible(true);
8: }
9: _startBufferSize = (_classField.length + 1) * 128;
10: }
</pre>
<table class="BlueLine" border="0" cellspacing="0" cellpadding="0" width="100%">
<tr>
<td bgcolor="000080" class="bluecell"><font size="2" face="Arial" color="010100"><b><img src="_.gif" width="1" height="2" alt="End example" border="0"></b></font></td>
</tr>
</table>
<table class="BlankSpace" border="0" cellspacing="0" cellpadding="0" width="100%">
<tr>
<td height="16"></td>
</tr>
</table>
</div>
</div>
<p class="para">Unfortunately, little can be done to reduce memory allocation here. <span class="fixed">ValueObject</span> needs access to the underlying field definitions to properly <a name="623"></a><a name="IDX-262"></a>implement meaningful versions of <span class="fixed">describe()</span>, <span class="fixed">equals()</span>, <span class="fixed">hashcode()</span>, and several other methods.</p>
<p class="para">The next trace in the ranking, trace 1, is shown in <a class="internaljump" href="#ch19list08">listing 19.8</a>.</p>
<div class="example">
<span class="example-title"><span class="example-titlelabel">Listing 19.8: </span>Trace 1 from the Sample in Listing 19.5</span><a name="624"></a><a name="ch19list08"></a>
<div class="formalbody">
<table class="BlueLine" border="0" cellspacing="0" cellpadding="0" width="100%">
<tr>
<td bgcolor="000080" class="bluecell"><font size="2" face="Arial" color="010100"><b><img src="_.gif" width="1" height="2" alt="Start example" border="0"></b></font></td>
</tr>
</table>
<pre class="literallayout">
TRACE 1:
<empty>
</pre>
<table class="BlueLine" border="0" cellspacing="0" cellpadding="0" width="100%">
<tr>
<td bgcolor="000080" class="bluecell"><font size="2" face="Arial" color="010100"><b><img src="_.gif" width="1" height="2" alt="End example" border="0"></b></font></td>
</tr>
</table>
<table class="BlankSpace" border="0" cellspacing="0" cellpadding="0" width="100%">
<tr>
<td height="16"></td>
</tr>
</table>
</div>
</div>
<p class="last-para">It turns out that trace 1 doesn't have a lot of meaningful information. I see this occasionally in HPROF traces but have never run across an explanation as to why it happens. My guess is that it's either an HPROF bug, memory associated with the JVM internally, or memory that no longer has a reference and is awaiting garbage collection. In practice, I'd move on to the next item in the ranking that doesn't belong to trace 1.</p>
</div>
</div>
</div><br>
<table width="100%" border="0" cellspacing="0" cellpadding="0">
<tr><td><div STYLE="MARGIN-LEFT: 0.15in;"><a href="toc.html"><img src="images/teamlib.gif" width="62" height="15" border="0" align="absmiddle" alt="Team LiB"></a></div></td>
<td align="right"><div STYLE="MARGIN-LEFT: 0.15in;">
<a href="LiB0123.html"><img src="images/previous.gif" width="62" height="15" border="0" align="absmiddle" alt="Previous Section"></a>
<a href="LiB0125.html"><img src="images/next.gif" width="41" height="15" border="0" align="absmiddle" alt="Next Section"></a>
</div></td></tr></table>
</body></html>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -