内存泄漏在哪里?

时间:2010-10-31 08:57:21

标签: scala memory-leaks

我使用InetAddress来解析IP地址,但现在如果IP不可用,则需要存储主机名。所以我介绍了一个类Host。

case class Host(name:String, ip:InetAddress) {
    import Host.{addressToBytes, compareSeqs}
    override def toString:String = if (ip!=null) {ip.getHostName} else {name}
}

object Host {
    implicit def stringToPattern(s:String): Pattern = Pattern.compile(s)
    val separators = Seq[Pattern]("\\.", ":")
    def separatedStrToBytes(s:String, separator:Pattern): Array[Byte] = {
        val fields = separator.split(s)
        var rv = new Array[Byte](fields.length);
        fields.map(_.toInt.toByte).copyToArray(rv, 0)
        rv
    }
    implicit def strToBytes(s:String): Array[Byte] = {
        for (sep <- separators)
            if (sep.matcher(s).find())
                return separatedStrToBytes(s, sep)
        null
    }
    implicit def strToHost(s:String):Host = {
        var name = s
        var ip:InetAddress = null
        try {
            val bytes = strToBytes(s)
            if (bytes != null) { 
                ip = InetAddress.getByAddress(bytes)
//              println( "parsed ip: "+s)
            }
        } catch {
            case e:UnknownHostException =>
        }
        if (ip==null) {
            ip = InetAddress.getByName(s)
        }
        new Host(name, ip)
    }
}

通过此更改,我的软件在separateStrToBytes中以“java.lang.OutOfMemoryError:GC开销限制超出”开始失败。我在这里做过任何记忆处理错误吗?

我感谢任何有关设计的评论。由于需要Array [Byte]作为InetAddress.getByAddress参数,我无法缩短解析时间。目标平台有Scala 2.7.7。

编辑:我已经用傻瓜替换了解析,发现我的程序在其他地方以后仍然会失败几兆字节的解析数据。每个替换String.split(s:String)与Pattern.split(s:String)和预编译模式使它运行稍长。这并不能解决我的问题,但现在可能会关闭这个问题。我仍然需要设计评论。

2 个答案:

答案 0 :(得分:4)

你的代码对2.8.0运行得很好(你应该考虑迁移到它,因为它已经是最终的并且相当稳定) - 没有检测到OutOfMemory。

您要求的一些优化:

implicit def strToBytes(s:String)= (for {separator <- separators find(_.matcher(s).find)} yield separatedStrToBytes(s, separator)) getOrElse null

implicit def separatedStrToBytes(s:String, separator:Pattern) = s split separator.pattern map(Integer.parseInt(_).toByte)

scala> import Host._
import Host._
scala> strToBytes("127.0.0.1")
res9: Array[Byte] = Array(127, 0, 0, 1)

答案 1 :(得分:1)

无需像这样手动解析URI,只需使用标准Java库中预先存在的URI类:http://download.oracle.com/javase/6/docs/api/java/net/URI.html

在任何情况下,

不要 使用URL类。它有一个疯狂的哈希算法,首先将主机名解析为IP地址,这是为什么这么多使用URL的Java工具(例如Eclipse更新管理器)启动时很慢的主要原因之一有网络连接