【问题标题】:Why does the profiler show large numbers of char[] instances when I am not creating any?当我不创建任何 char[] 实例时,为什么探查器会显示大量实例?
【发布时间】:2009-12-31 13:48:55
【问题描述】:

我正在运行递归操作的 NetBeans 配置文件,其中包括创建具有 java.lang.String 字段的类。在类列表中,在配置文件堆转储中,字符串字段的数量对应于按预期创建的类的数量,但也有类似数量的 char[] 实例。 char 数组占内存使用量的近 70%(!),而 String 字段占约 7%。

这里发生了什么?以及如何减少char[] 实例的数量?

谢谢

【问题讨论】:

    标签: java profiling


    【解决方案1】:

    看看String source code。 String 对象本身包含一个缓存的哈希码、字符数的计数(同样,出于优化目的)、偏移量(因为 String.substr() 指向原始字符串数据)字符数组,其中包含实际的字符串数据。因此,您的指标显示 String 消耗相对较少,但大部分内存由底层字符数组占用。

    【讨论】:

      【解决方案2】:

      char数组占近70% 的内存使用(!),而 字符串字段约占7%

      这是内存分析的精妙之处,称为“保留大小”和“浅层大小”:

      • Shallow size是指一个对象占用了多少内存,不包括它所包含的任何子对象。基本上,这意味着原始字段。
      • 保留大小是浅层大小加上该对象引用的其他对象的大小,但只有那些仅由该对象引用的其他对象(解释起来很棘手,简单的概念)。

      字符串就是一个完美的例子。它包含一些原始字段,以及char[]char[] 占内存使用量的绝大部分。 String 的浅层尺寸非常小,但保留的尺寸要大得多,因为其中包括char[]

      NetBeans 分析器可能会为您提供浅尺寸,这不是一个非常有用的数字,但很容易计算。保留大小会将char[] 内存使用量合并到String 内存使用量中,但计算保留大小的计算量很大,因此分析器在明确要求之前不会计算出来。

      【讨论】:

      • 我认为你的意思是 char[],而不是 byte[]
      • @PeterLawrey 哦,讽刺。如今,由于 Java 9,byte[] 确实是正确的类型(但这也会改变最初的问题)......
      【解决方案3】:

      Sun 的 Java 实现中的 String 类使用 char[] 来存储字符数据。

      我相信这可以通过使用调试器查看String 的内容或使用反射查看String 对象的内部结构来验证,而无需查看源代码。

      因此,很难减少正在创建的char[] 的数量,除非正在创建的String 实例的数量有所减少。

      【讨论】:

        【解决方案4】:

        字符串由 char 数组支持,因此我认为您不能在不减少字符串的情况下减少 char[] 实例的数量。

        您是否尝试删除一些字符串以查看 char[] 是否也下降?

        【讨论】:

          猜你喜欢
          • 2015-09-16
          • 2019-04-07
          • 2012-01-10
          • 1970-01-01
          • 1970-01-01
          • 2019-06-13
          • 2018-08-03
          • 2012-08-17
          • 1970-01-01
          相关资源
          最近更新 更多