当日志显示很多GC命中时,我们需要更改哪些代码? [英] When log shows a lot of GC hits, what code change shall we need?

查看:127
本文介绍了当日志显示很多GC命中时,我们需要更改哪些代码?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

当日志显示大量垃圾收集命中时,我们需要更改哪些代码?

我们是否需要释放一些对象?

我们是否会加快带有对象的代码这个代码对很多名字运行:
$ b

编辑

  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释放了13344个对象/ 523736字节在73ms 
05-17 14:05:08.269:DEBUG / dalvikvm(8823):GC释放13341个对象/ 524608字节在72ms
05-17 14:05:08.889:DEBUG / dalvikvm(8823) :GC在72ms内释放了13302个对象/ 525112个字节
05-17 14:05:09.519:DEBUG / dalvikvm(8823):GC在72ms中释放了13151个对象/ 524360个字节
05-17 14:05: 10.089:DEBUG / dalvikvm(8823):GC已释放13137个对象/ 523872个字节,长度为72ms
05-17 14:05:10.779:DEBUG / dalvikvm(8823):GC已释放13377个对象/ 524384个字节b 05-17 14:05:11.389:DEBUG / dalvikvm(8823):GC释放了13289个对象/ 524656个字节在72ms
05-17 14:05:12.049:DEBUG / dalvikvm(8823):GC释放了13113个对象/ 524336字节在71ms
05-17 14:05:12.299:DEBUG / dalvikvm(4864):GC在358ms中释放206个对象/ 10216字节
05-17 14:05:12.769:DEBUG / dalvikvm (8823):GC释放了13289 ob在68ms中释放了13165个对象/ 524192个字节
05-17 14:05:14.099:DEBUG / dalvikvm(8823):在75ms中有524272个字节
05-17 14:05:13.449:DEBUG / dalvikvm(8823):GC释放了13221个对象/ 524016个字节在73ms
05-17 14:05:14.719:DEBUG / dalvikvm(8823):GC释放了13179个对象/ 524768个字节在73ms
05-17 14:05:15.349:DEBUG / dalvikvm(8823):GC释放了13306个对象/ 524328个字节在73ms
05-17 14:05:15.999:DEBUG / dalvikvm(8823):GC释放了13280个对象/ 523536个字节73ms
05-17 14:05:16.589:DEBUG / dalvikvm(8823):GC释放了13314个对象/ 524928字节在68ms
05-17 14:05:17.249:DEBUG / dalvikvm(8823) GC在73毫秒释放了13217个对象/ 524792个字节
05-17 14:05:17.929:DEBUG / dalvikvm(8823):GC释放了13176个对象/ 524104字节在68ms
05-17 14:05:18.449 :DEBUG / dalvikvm(9926):GC释放了10341个对象/ 558184个字节(488ms)
05-17 14:05:18.689:DEBUG / dalvikvm(8823):GC释放了13485个对象/ 524664字节75ms
05-17 14:05:19.279:DEBUG / dalvikvm( 8823):GC在67ms中释放了13337个对象/ 523816个字节
05-17 14:05:19.909:DEBUG / dalvikvm(8823):GC在72ms中释放了13269个对象/ 524784个字节
05-17 14: 05:20.419:DEBUG / dalvikvm(8823):GC已释放13489个对象/ 524416个字节在72ms
05-17 14:05:21.069:DEBUG / dalvikvm(8823):GC释放了12948个对象/ 523712个字节b $ b 05-17 14:05:21.659:DEBUG / dalvikvm(8823):GC在68ms中释放了13436个对象/ 525040个字节

你认为这太多了吗?

解决方案

频繁的垃圾回收可能是由一些的东西。例如:


  • 您的应用程序可能会创建太多的临时对象。

  • 堆可能太小。如果您在应用程序上运行内存分析器,前两个问题将会显示出来,并且解决方案通常是不言而喻。



    通过检查GC日志可以看出第三个问题,并指出每个GC只能成功回收相对较少的内存。理想情况下,您希望GC在每次运行时收回50%或更多的堆。此修复通常是使用JVM的 -Xmx 命令行选项来增加最大堆大小。


    我们是否会加快拒绝对象的代码?


    一般来说不会。回收是痛苦的,不能保证它会成功。例如,您将很难在Java标准库和第三方库中获取许多类来回收内部数据结构。



    您应该只求助于显式回收如果所有其他尝试解决问题的尝试都失败,则返回对象最简单的解决方案往往只是给应用程序一个更大的堆。



    编辑



    在编辑的问题中减少代码的内存使用量的一种方法是更改​​:

      StringBuilder sb = new StringBuilder() ; 

      StringBuilder sb = new StringBuilder(s.length()); 

    这可能有助于重复使用StringBuilder,但如果此代码给了您过多的GC速率,那么问题更可能是存在内存泄漏(应用程序中的其他位置)或者您的堆太小。 (人们没有意识到这一点,但是每个Java字符串都有一个很大的内存开销,如果我的心算是正确的话,那么这个开销就像48字节一样。)

    < GC编辑2



    GC日志表示每次GC运行时都会回收50000Kb,并强烈建议内存使用量不会增加。 (后者是个好消息,它几乎排除了内存泄漏。)我认为您需要使用 -Xmx 来增加堆大小, -Xms 选项。您希望在每个GC周期中回收几个兆字节,以减少每字节回收的平均GC开销。

    另外一个让我吃惊的事情是,也许你可以改变你的 removeAccents 方法,这样它只会在结果字符串与输入字符串不同时创建一个新的字符串。换句话说,如果没有重音符,它应该只返回输入的字符串。


    When log shows a lot of Garbage Collection hits, what code change shall we need?
    Do we need to free some objects?
    Will we speed up the code with object reusal?

    EDIT

    I run this code against a lot of names:

     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

    log of 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
    

    Do you consider this is too much?

    解决方案

    Frequent garbage collection can be caused by a number of things. For example:

    • Your application may be creating too many temporary object.

    • Memory leaks caused by your application keeping references to objects that are no longer required.

    • The heap may be too small.

    The first two problems will be revealed if you run a memory profiler on your application, and the solution will usually be self evident.

    The third problem can be seen by examining the GC logs, and noting that each GC run only succeeds in reclaiming a relatively small amount of memory. Ideally, you want the GC to reclaim 50% or more of the heap each time it runs. The fix is typically to increase the maximum heap size using the JVM's -Xmx command-line option.

    Will we speed up the code with object reusal?

    Generally speaking no. Recycling is painful, there is no guarantee that it will succeed. For example, you will have a hard time getting many classes in the Java standard library and 3rd-party libraries to recycle internal data structures.

    You should only resort to explicitly recycling objects if all other attempts to fix the problem have failed. The simplest solution is often just to give the application a bigger heap.

    EDIT

    One way to reduce memory usage for the code in the edited question is to change:

       StringBuilder sb = new StringBuilder();
    

    to

       StringBuilder sb = new StringBuilder(s.length());
    

    It might help to reuse the StringBuilder as well, but if this code is giving you excessive GC rates then the problem is more likely to be that there is a memory leak (somewhere else in your application) or that your heap is simply too small. (People don't realize this, but there is a significant memory overhead for every Java String ... something like 48 bytes if my mental arithmetic is correct.)

    EDIT 2

    The GC logs say that you are reclaiming 50000Kb each time the GC runs, and they strongly suggest that the memory usage is not increasing. (The latter is good news; it pretty much rules out a memory leak.) I think you need to increase the heap size using the -Xmx and -Xms options. You want to be reclaiming a few megabytes in each GC cycle to reduce the average GC overhead per byte reclaimed.

    The other thing that struck me is that maybe you can change your removeAccents method so that it only creates a new String if the result String will be different to the input String. In other words, if there are no accents it should just return the input String.

    这篇关于当日志显示很多GC命中时,我们需要更改哪些代码?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆