当日志显示大量垃圾收集命中时,我们需要更改哪些代码?
我们需要释放一些对象吗?
我们会通过对象重用来加速代码吗?
EDIT
我针对很多名称运行此代码:
public static String removeAccents(String s) {
if (s == null)
return null;
StringBuilder sb = new StringBuilder();
int n = s.length();
for (int i = 0; i < n; i++) {
char c = s.charAt(i);
int pos = UNICODE.indexOf(c);
if (pos > -1) {
sb.append(PLAIN_ASCII.charAt(pos));
} else {
sb.append(c);
}
}
return sb.toString();
}
EDIT2
GC 日志
05-17 14:05:07.629: DEBUG/dalvikvm(8823): GC freed 13344 objects / 523736 bytes in 73ms
05-17 14:05:08.269: DEBUG/dalvikvm(8823): GC freed 13341 objects / 524608 bytes in 72ms
05-17 14:05:08.889: DEBUG/dalvikvm(8823): GC freed 13302 objects / 525112 bytes in 72ms
05-17 14:05:09.519: DEBUG/dalvikvm(8823): GC freed 13151 objects / 524360 bytes in 72ms
05-17 14:05:10.089: DEBUG/dalvikvm(8823): GC freed 13377 objects / 524384 bytes in 71ms
05-17 14:05:10.779: DEBUG/dalvikvm(8823): GC freed 13137 objects / 523872 bytes in 72ms
05-17 14:05:11.389: DEBUG/dalvikvm(8823): GC freed 13289 objects / 524656 bytes in 72ms
05-17 14:05:12.049: DEBUG/dalvikvm(8823): GC freed 13113 objects / 524336 bytes in 71ms
05-17 14:05:12.299: DEBUG/dalvikvm(4864): GC freed 206 objects / 10216 bytes in 358ms
05-17 14:05:12.769: DEBUG/dalvikvm(8823): GC freed 13289 objects / 524272 bytes in 75ms
05-17 14:05:13.449: DEBUG/dalvikvm(8823): GC freed 13165 objects / 524192 bytes in 68ms
05-17 14:05:14.099: DEBUG/dalvikvm(8823): GC freed 13221 objects / 524016 bytes in 73ms
05-17 14:05:14.719: DEBUG/dalvikvm(8823): GC freed 13179 objects / 524768 bytes in 73ms
05-17 14:05:15.349: DEBUG/dalvikvm(8823): GC freed 13306 objects / 524328 bytes in 73ms
05-17 14:05:15.999: DEBUG/dalvikvm(8823): GC freed 13280 objects / 523536 bytes in 73ms
05-17 14:05:16.589: DEBUG/dalvikvm(8823): GC freed 13314 objects / 524928 bytes in 68ms
05-17 14:05:17.249: DEBUG/dalvikvm(8823): GC freed 13217 objects / 524792 bytes in 73ms
05-17 14:05:17.929: DEBUG/dalvikvm(8823): GC freed 13176 objects / 524104 bytes in 68ms
05-17 14:05:18.449: DEBUG/dalvikvm(9926): GC freed 10341 objects / 558184 bytes in 488ms
05-17 14:05:18.689: DEBUG/dalvikvm(8823): GC freed 13485 objects / 524664 bytes in 75ms
05-17 14:05:19.279: DEBUG/dalvikvm(8823): GC freed 13337 objects / 523816 bytes in 67ms
05-17 14:05:19.909: DEBUG/dalvikvm(8823): GC freed 13269 objects / 524784 bytes in 72ms
05-17 14:05:20.419: DEBUG/dalvikvm(8823): GC freed 13389 objects / 524416 bytes in 72ms
05-17 14:05:21.069: DEBUG/dalvikvm(8823): GC freed 12948 objects / 523712 bytes in 72ms
05-17 14:05:21.659: DEBUG/dalvikvm(8823): GC freed 13436 objects / 525040 bytes in 68ms
您认为这太过分了吗?
频繁的垃圾收集可能由多种原因引起。例如:
如果您在应用程序上运行内存分析器,前两个问题就会显现出来,并且解决方案通常是不言而喻的。
第三个问题可以通过检查 GC 日志来发现,并注意到每次 GC 运行仅成功回收了相对少量的内存。理想情况下,您希望 GC 每次运行时回收 50% 或更多的堆空间。解决方法通常是使用 JVM 增加最大堆大小-Xmx
命令行选项。
我们会通过对象重用来加速代码吗?
一般来说没有。回收是痛苦的,并不能保证它会成功。例如,您将很难获得Java标准库和第三方库中的许多类来回收内部数据结构。
仅当修复问题的所有其他尝试均失败时,才应显式回收对象。最简单的解决方案通常只是为应用程序提供更大的堆。
EDIT
减少编辑问题中代码的内存使用量的一种方法是更改:
StringBuilder sb = new StringBuilder();
to
StringBuilder sb = new StringBuilder(s.length());
重用 StringBuilder 也可能有所帮助,但如果此代码给您带来过高的 GC 速率,那么问题很可能是存在内存泄漏(应用程序中的其他位置)或者您的堆太小。 (人们没有意识到这一点,但每个 Java String 都有很大的内存开销……如果我的心算正确的话,大约是 48 个字节。)
EDIT 2
GC 日志显示每次 GC 运行时您都会回收 50000Kb,并且它们强烈表明内存使用量没有增加。 (后者是个好消息;它几乎排除了内存泄漏。)我认为您需要使用-Xmx
and -Xms
选项。您希望在每个 GC 周期中回收几兆字节以减少average回收的每个字节的 GC 开销。
另一件让我印象深刻的事情是也许你可以改变你的removeAccents
方法,以便仅在结果字符串与输入字符串不同时才创建新字符串。换句话说,如果没有重音符号,它应该只返回输入字符串。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)