避免 Scala 内存泄漏

编程入门 行业动态 更新时间:2024-10-21 11:27:00
本文介绍了避免 Scala 内存泄漏 - Scala 构造函数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述

我正在阅读Scala 编程"一书,但在第 6 章中实现类 Rational 时遇到了一个小问题.

I was working through the "Programming in Scala" book, and was struck by a bit of a problem in the implementation of the class Rational in Chapter 6.

这是我的 Rational 类的初始版本(基于本书)

This is my initial version of the Rational class (based on the book)

class Rational(numerator: Int, denominator: Int) { require(denominator != 0) private val g = gcd(numerator.abs, denominator.abs) val numer = numerator / g val denom = denominator / g override def toString = numer + "/" + denom private def gcd(a: Int, b: Int): Int = if(b == 0) a else gcd(b, a % b) // other methods go here, neither access g }

这里的问题是字段 g 在类的整个生命周期中都会保留,即使再也不会被访问.这个问题可以通过运行下面的模拟程序看到:

The problem here is that the field g remains for the lifetime of the class, even if never again accessed. This problem can be seen by running the following mock program:

object Test extends Application { val a = new Rational(1, 2) val fields = a.getClass.getDeclaredFields for(field <- fields) { println("Field name: " + field.getName) field.setAccessible(true) println(field.get(a) + "\n") } }

它的输出将是:

Field: denom 2 Field: numer 1 Field: g 1

我在 Scala Wiki 上找到的解决方案涉及以下内容:

A solution I found at the Scala Wiki involves the following:

class Rational(numerator: Int, denominator: Int) { require(denominator != 0) val (numer, denom) = { val g = gcd(numerator.abs, denominator.abs) (numerator / g, denominator / g) } override def toString = numer + "/" + denom private def gcd(a: Int, b: Int): Int = if(b == 0) a else gcd(b, a % b) // other methods go here }

此处,字段 g 仅在其块的本地,但是,运行小型测试应用程序时,我发现了另一个字段 x$1,它保留了由 (numer, denom)!

Here, the field g is only local to its block, but, running the small test application, I found another field x$1 which keeps a copy of the tuple consisting of (numer, denom)!

Field: denom 2 Field: numer 1 Field: x$1 (1,2)

有没有什么办法可以用上面的算法在Scala中构造一个有理数,而不会造成任何内存泄漏?

Is there any way to construct a rational in Scala with the above algorithm, without causing any memory leaks?

谢谢,

弗拉维乌·西皮根

推荐答案

你可以这样做:

val numer = numerator / gcd(numerator.abs, denominator.abs) val denom = denominator / gcd(numerator.abs, denominator.abs)

当然,您必须进行两次计算.但是优化通常是内存/空间和执行时间之间的权衡.

Of course you'd have to do the calculation twice. But then optimizations are often a trade-off between memory/space and execution time.

也许还有其他方法,但是程序可能会变得过于复杂,如果有一个地方的优化很少为时过早,那就是脑力优化:).例如,您可能可以这样做:

Maybe there are other ways too, but then the program might get overly complex, and if there's one place where optimization is rarely premature, it's brain power optimization :). For instance, you could probably do this:

val numer = numerator / gcd(numerator.abs, denominator.abs) val denom = denominator / (numerator / numer)

但这并不一定会使代码更易于理解.

But it doesn't necessarily make the code more understandable.

(注意:我实际上没有尝试过,所以使用风险自负.)

(Note: I didn't actually try this, so use at your own risk.)

更多推荐

避免 Scala 内存泄漏

本文发布于:2023-11-16 11:46:19,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1603994.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:内存   Scala

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!