当前位置: 首页 > 知识库问答 >
问题:

Scala shell中的垃圾收集

都浩淼
2023-03-14
import scala.util.Random

def uuid = java.util.UUID.randomUUID.toString

def generateRandomList(size: Int): List[Float] = {
    List.fill(size)(Random.nextFloat)
}

val numDimensions = 1000
val numberToWrite = 20000

val out = for ( i <- 1 to numberToWrite) yield {
      val randomList = generateRandomList(numDimensions)
      (uuid, randomList)  // trying tuples insread
}
java.lang.OutOfMemoryError: GC overhead limit exceeded
  at java.lang.Float.valueOf(Float.java:433)
  at scala.runtime.BoxesRunTime.boxToFloat(BoxesRunTime.java:73)
  at $anonfun$generateRandomArray$1.apply(<console>:14)
  at scala.collection.generic.GenTraversableFactory.fill(GenTraversableFactory.scala:90)
  at .generateRandomArray(<console>:14)
  at $anonfun$1.apply(<console>:17)
  at $anonfun$1.apply(<console>:16)
  at scala.collection.TraversableLike$$anonfun$map$1.apply(TraversableLike.scala:234)
  at scala.collection.TraversableLike$$anonfun$map$1.apply(TraversableLike.scala:234)
  at scala.collection.immutable.Range.foreach(Range.scala:160)
  at scala.collection.TraversableLike$class.map(TraversableLike.scala:234)
  at scala.collection.AbstractTraversable.map(Traversable.scala:104)
  ... 20 elided
scala> val heapSize = Runtime.getRuntime().totalMemory(); // Get current size of heap in bytes
heapSize: Long = 212860928

scala> val heapMaxSize = Runtime.getRuntime().maxMemory(); // Get maximum size of heap in bytes. The heap cannot     grow beyond this size.// Any attempt will result in an OutOfMemoryException.

heapMaxSize: Long = 239075328

scala> val heapFreeSize = Runtime.getRuntime().freeMemory();  // Get amount of free memory within the heap in bytes.     This size will increase // after garbage collection and decrease as new objects are created.

heapFreeSize: Long = 152842176

尽管我的最大可用堆大小似乎大于我认为我需要的粗略内存量,但我还是尝试通过./scala-j-xmx2g来增加堆大小([4])。虽然这解决了我的问题,但最好知道是否有更好的方法来创建这种随机数据,从而避免我不得不增加JVM可用的内存?因此,我有以下三个问题,如果有人能回答,我将不胜感激:

>

  • 在Scala中,尤其是在Scala shell中,垃圾回收何时发生?在上面的命令中,有什么可以收集,那么为什么要调用GC(对不起,第二部分可能表明我对GC缺乏了解)?

    我对占用的内存量的粗略计算是否有效(当然,我预计列表和元组的开销会更大一些,但假设相对来说不会那么多)?如果是这样,为什么我的最大堆大小(239e6字节)应该涵盖内存不足?如果没有,我使用了什么额外的内存?

    1. 错误java.lang.OutofMemoryError:超出GC开销限制
    2. 在Java 8中字符串使用多少内存?
    3. 如何查看应用程序正在使用的当前堆大小?
    4. 增加Scala的JVM堆大小?
  • 共有1个答案

    楚浩然
    2023-03-14

    为了回答REPL特定的部分:

    https://issues.scala-lang.org/browse/si-4331

    进行大量分配的人通常更喜欢arraybuffer

    scala> var x = new Array[Byte](20000000 * 4)
    x: Array[Byte] = Array(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ...
    scala> x = null
    x: Array[Byte] = null
    
    scala> x = new Array[Byte](20000000 * 4)
    x: Array[Byte] = [B@475530b9
    
    scala> x = null
    x: Array[Byte] = null
    
    scala> x = new Array[Byte](20000000 * 4)
    java.lang.OutOfMemoryError: Java heap space
      ... 32 elided
    
     类似资料:
    • Kubernetes 垃圾收集器的角色是删除指定的对象,这些对象曾经有但以后不再拥有 Owner 了。 注意:垃圾收集是 beta 特性,在 Kubernetes 1.4 及以上版本默认启用。 Owner 和 Dependent 一些 Kubernetes 对象是其它一些的 Owner。例如,一个 ReplicaSet 是一组 Pod 的 Owner。具有 Owner 的对象被称为是 Owner

    • 垃圾回收 我们对生产中花了很多时间来调整垃圾回收。垃圾回收的关注点与Java大致相似,尽管一些惯用的Scala代码比起惯用的Java代码会容易产生更多(短暂的)垃圾——函数式风格的副产品。Hotspot的分代垃圾收集通常使这不成问题,因为短暂的(short-lived)垃圾在大多情形下会被有效的释放掉。 在谈GC调优话题前,先看看这个Attila的报告,它阐述了我们在GC方面的一些经验。 Scal

    • 对于开发者来说,JavaScript 的内存管理是自动的、无形的。我们创建的原始值、对象、函数……这一切都会占用内存。 当我们不再需要某个东西时会发生什么?JavaScript 引擎如何发现它并清理它? 可达性(Reachability) JavaScript 中主要的内存管理概念是 可达性。 简而言之,“可达”值是那些以某种方式可访问或可用的值。它们一定是存储在内存中的。 这里列出固有的可达值的

    • 垃圾收集,引用计数,显式分配 和所有的现代语言一样,OCaml提供垃圾收集器,所以你不用像C/C++一样显式地分配和释放内存。 JWZ在他的文章 "Java sucks" rant(Java蛋疼(怒)!): 第一个好家伙是Java没有 free()。其他的都没有所谓了。这几乎掩盖了所有的缺点,不管有多糟糕, 这个有点让后续文档基本都没有意义了,但是...(译注:但是啥大家自己看吧) OCaml的垃

    • 本文向大家介绍Java垃圾收集,包括了Java垃圾收集的使用技巧和注意事项,需要的朋友参考一下 示例 C ++方法-新增和删除 在像C ++这样的语言中,应用程序负责管理动态分配的内存所使用的内存。当使用new运算符在C ++堆中创建对象时,需要相应地使用delete运算符来处置该对象: 如果程序忘记了delete一个对象而只是“忘记”了该对象,则关联的内存将丢失给应用程序。这种情况的术语是内存泄

    • JavaScript 具有自动垃圾收集机制,也就是说,执行环境会负责管理代码执行过程中使用的内存。 而在C 和C++之类的语言中,开发人员的一项基本任务就是手工跟踪内存的使用情况,这是造成许多问题的一个根源。在编写JavaScript 程序时,开发人员不用再关心内存使用问题,所需内存的分配以及无用内存的回收完全实现了自动管理。这种垃圾收集机制的原理其实很简单:找出那些不再继续使用的变量,然后释放其