Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/string/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
String 单字符串列表的内存分配率高于多字符串列表_String_List_Scala_Scala Collections_Memory Consumption - Fatal编程技术网

String 单字符串列表的内存分配率高于多字符串列表

String 单字符串列表的内存分配率高于多字符串列表,string,list,scala,scala-collections,memory-consumption,String,List,Scala,Scala Collections,Memory Consumption,考虑以下基准测试,它分配长度为1而不是8的字符串列表 @State(Scope.Benchmark) @BenchmarkMode(Array(Mode.Throughput)) class SoMemory { val size = 1_000_000 @Benchmark def a: List[String] = List.fill[String](size)(Random.nextString(1)) @Benchmark def b: List[String] = List

考虑以下基准测试,它分配长度为1而不是8的字符串列表

@State(Scope.Benchmark)
@BenchmarkMode(Array(Mode.Throughput))
class SoMemory {
  val size = 1_000_000
  @Benchmark def a: List[String] = List.fill[String](size)(Random.nextString(1))
  @Benchmark def b: List[String] = List.fill[String](size)(Random.nextString(8))
}
其中sbt jmh:run-i10-wi10-f2-t1-prof gc bench.SoMemory给出

请注意,较小的字符串具有显著较高的gc.alloc.rate

举例来说,当字符串越小,内存占用越小时,为什么在第一种情况下内存消耗越高

class ZarA { val x = List.fill[String](1_000_000)(Random.nextString(1)) }
class ZarB { val x = List.fill[String](1_000_000)(Random.nextString(8)) }
正如所料,ZarA的占地面积较小,约为72MB

相比之下,ZarB的占地面积更大,约为80MB

视觉记忆行为

ZarA-使用了129MB的堆

ZarB-使用堆91 MB


分配速率是指分配内存的速度,即每单位时间分配的内存量。它没有告诉我们任何关于总内存分配的信息


找到更小的连续内存区域总是比找到更大的连续内存区域更容易,因此,例如,分配长度为1的1000个字符串比分配长度为8的1000个字符串花费的时间要少,导致更高的分配率和更少的总内存消耗。

分配率是指您可以以多快的速度分配每单位时间分配的内存量。它没有告诉我们任何关于总内存分配的信息


找到更小的连续内存区域总是比找到更大的连续内存区域更容易,因此,例如,分配长度为1的1000个字符串比分配长度为8的1000个字符串花费的时间要少,导致更高的分配率和更少的总内存消耗。

使用似乎表明ZarA消耗更多的总内存。更高的gc.alloc.rate.norm是否表示更高的总内存消耗?norm代表规范化,但它仍然是速率速度,而不是总体分配。这两个JMH mertics都没有告诉我们内存的总使用量,我认为JMH不是衡量内存消耗的合适工具。对于这一点,一些剖析器会更好。从运行时打印内存会告诉您某个时间点的内存使用情况,我们不知道它是在GC之前还是在分析器可以强制GC为我们提供更清晰的图片之后,所以我认为它可能只是作为内存使用直方图的输入才有意义。尝试强制GC并查看分配对象的列表,这应该告诉你一些有趣的事情。在使用System.GC强制GC之后,ZarA案例的堆使用量约为75 MB,而ZarB案例的堆使用量约为85 MB,这确实与JOL预测类似。谢谢,这澄清了它。使用似乎表明ZarA消耗了更多的总内存。更高的gc.alloc.rate.norm是否表示更高的总内存消耗?norm代表规范化,但它仍然是速率速度,而不是总体分配。这两个JMH mertics都没有告诉我们内存的总使用量,我认为JMH不是衡量内存消耗的合适工具。对于这一点,一些剖析器会更好。从运行时打印内存会告诉您某个时间点的内存使用情况,我们不知道它是在GC之前还是在分析器可以强制GC为我们提供更清晰的图片之后,所以我认为它可能只是作为内存使用直方图的输入才有意义。尝试强制GC并查看分配对象的列表,这应该告诉你一些有趣的事情。在使用System.GC强制GC之后,ZarA案例的堆使用量约为75 MB,而ZarB案例的堆使用量约为85 MB,这确实与JOL预测类似。谢谢,这就澄清了。
SoMemory.a:·gc.alloc.rate         thrpt   20        3870.364 ±      120.687  MB/sec
SoMemory.b:·gc.alloc.rate         thrpt   20        2763.961 ±       89.654  MB/sec
class ZarA { val x = List.fill[String](1_000_000)(Random.nextString(1)) }
class ZarB { val x = List.fill[String](1_000_000)(Random.nextString(8)) }
example.ZarA@15975490d footprint:
     COUNT       AVG       SUM   DESCRIPTION
   1000000        24  24000000   [C
         1        16        16   example.ZarA
   1000000        24  24000000   java.lang.String
   1000000        24  24000000   scala.collection.immutable.$colon$colon
         1        16        16   scala.collection.immutable.Nil$
   3000002            72000032   (total)
example.ZarB@15975490d footprint:
     COUNT       AVG       SUM   DESCRIPTION
   1000000        32  32000000   [C
         1        16        16   example.ZarB
   1000000        24  24000000   java.lang.String
   1000000        24  24000000   scala.collection.immutable.$colon$colon
         1        16        16   scala.collection.immutable.Nil$
   3000002            80000032   (total)