【发布时间】:2020-07-05 11:01:37
【问题描述】:
考虑以下基准,它分配长度为 1 的 String 的 List 与长度为 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 -i 10 -wi 10 -f 2 -t 1 -prof gc bench.SoMemory" 给出的地方
[info] Benchmark Mode Cnt Score Error Units
[info] SoMemory.a thrpt 20 16.650 ± 0.519 ops/s
[info] SoMemory.a:·gc.alloc.rate thrpt 20 3870.364 ± 120.687 MB/sec
[info] SoMemory.a:·gc.alloc.rate.norm thrpt 20 255963282.822 ± 61.012 B/op
[info] SoMemory.a:·gc.churn.PS_Eden_Space thrpt 20 3862.090 ± 161.598 MB/sec
[info] SoMemory.a:·gc.churn.PS_Eden_Space.norm thrpt 20 255331784.446 ± 4839869.981 B/op
[info] SoMemory.a:·gc.churn.PS_Survivor_Space thrpt 20 25.893 ± 1.433 MB/sec
[info] SoMemory.a:·gc.churn.PS_Survivor_Space.norm thrpt 20 1711320.051 ± 64870.177 B/op
[info] SoMemory.a:·gc.count thrpt 20 318.000 counts
[info] SoMemory.a:·gc.time thrpt 20 45183.000 ms
[info] SoMemory.b thrpt 20 2.859 ± 0.092 ops/s
[info] SoMemory.b:·gc.alloc.rate thrpt 20 2763.961 ± 89.654 MB/sec
[info] SoMemory.b:·gc.alloc.rate.norm thrpt 20 1063705990.899 ± 503.169 B/op
[info] SoMemory.b:·gc.churn.PS_Eden_Space thrpt 20 2768.433 ± 101.742 MB/sec
[info] SoMemory.b:·gc.churn.PS_Eden_Space.norm thrpt 20 1065601049.380 ± 25878705.006 B/op
[info] SoMemory.b:·gc.churn.PS_Survivor_Space thrpt 20 20.838 ± 1.063 MB/sec
[info] SoMemory.b:·gc.churn.PS_Survivor_Space.norm thrpt 20 8015328.037 ± 236873.550 B/op
[info] SoMemory.b:·gc.count thrpt 20 234.000 counts
[info] SoMemory.b:·gc.time thrpt 20 37696.000 ms
注意较小的字符串如何显着提高gc.alloc.rate
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
为什么在第一种情况下,较小的字符串应该具有较小的内存占用,例如,JOL 给出的内存消耗似乎更高
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
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)
与 ZarB 大约 80MB 的更大占用空间相比
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)
VisualVM 内存行为
ZarA - 已用堆 129 MB
ZarB - 已用堆 91 MB
【问题讨论】:
标签: string list scala scala-collections memory-consumption