【问题标题】:Format a MAC address in Android/Java without creating unnecessary garbage在 Android/Java 中格式化 MAC 地址,不会产生不必要的垃圾
【发布时间】:2013-08-25 04:29:09
【问题描述】:

我正在开发一个 Android 应用程序,该应用程序需要每秒处理数千个数据包,同时提取和格式化每个帧的 MAC 地址。问题是垃圾收集器每秒运行十几次并停止我的应用程序,这反过来又让我错过了数据包。我已经尽可能(我认为)避免创建新对象。

我在 DDMS 中使用了分配跟踪器,并确定正在清理的 99% 的垃圾来自以下方法。这是我正在使用的代码:

void parseMac() { 
    hex_sb.setLength(0);

    for (hex_counter = 0; hex_counter < 6; hex_counter++) {
        hex_sb.append(String.format("%02X", parser_packet_bytes[parser_skip + hex_counter])); 
        if (!(hex_counter == 5)) {
            hex_sb.append(":");
        }
    }

    formatted_mac = hex_sb.toString();
}

hex_sb 是一个可以重复使用的 StringBuilder。 hex_counter 是 MAC 地址中的字节数(字节来自 parser_packet_bytes,一个 byte[])。如果它不是 MAC 的最后一个字节,则附加一个“:”以进行正确格式化。 formatted_mac 是一个类范围的字符串,用于存储格式化的 MAC。根据分配跟踪器,唯一的问题是使用 String.format 的行。

我对 StackOverflow 专家的问题是:如何重写上述方法以减少(最好没有)垃圾的产生?

【问题讨论】:

  • 为什么?您真的每秒接收来自数千个不同对等方的信息吗?还是您每秒从同一对等方接收数千帧?在后一种情况下,每个帧中的 MAC 地址将相同。但是没有理由不能在没有循环的情况下在单个 format() 调用中格式化整个 MAC 地址。这会将垃圾除以 6。

标签: java android garbage-collection


【解决方案1】:

不要使用相当昂贵的String.format(),只需手动附加半字节即可。不幸的是,ASCII/UTF-8 中的数字和字母不是连续的,所以我是这样处理的:

static final char HEX_DIGITS[] = "01234567890abcdef".toCharArray();
...
hex_sb.append(HEX_DIGITS[thisByte >> 4]).append(HEX_DIGITS[thisByte & 0xf]);

由于这是一个 MAC 地址(已知长度)并且被大量调用,我可能会展开整个事情,包括附加冒号/句点(应该是 char,而不是 String)。如果它真的对速度至关重要,请管理您自己的char[] 并将其提供给String#new(char[])。您可以避免以这种方式重新插入分隔符。

【讨论】:

  • 谢谢!我没有想过要这样尝试。这种方法彻底解决了问题,效果很好。
  • 我之前正在验证我的结果,看起来这种方法无法正常工作。例如:当我使用这些字节作为 MAC 地址时: '0x58' '0x6D' '0x8F' '0xBA' '0xF5' '0x81' hex_sb.getString() 给我 "58:6C:8E:A0:E5:81 ”。我对位移不是很精通,非常感谢您的洞察力。
  • ...几乎不可能以这种方式失败。有可能与 Java all-signed-all-the-time 的失败有关,但这种失败模式根本没有意义。如果您遇到此故障,请发布完整的测试用例。
【解决方案2】:

每个新的 MAC 都需要一个新的字符串,因为字符串是不可变的,所以你无能为力。至于 StringBuilder 操作,它不会创建任何垃圾,因为 StringBuilder 将在 setLength(0) 上重用相同的 char 数组并追加,它只会更改当前位置。唯一有帮助的是直接使用 StringBuilder 而不将其转换为 String (如果可能的话)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-05-24
    • 1970-01-01
    • 2014-07-12
    • 1970-01-01
    • 1970-01-01
    • 2011-11-15
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多