当我不创建任何 char[] 实例时,为啥探查器会显示大量实例?

Posted

技术标签:

【中文标题】当我不创建任何 char[] 实例时,为啥探查器会显示大量实例?【英文标题】: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[] 实例的数量?

谢谢

【问题讨论】:

【参考方案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[] 是否也下降?

【讨论】:

以上是关于当我不创建任何 char[] 实例时,为啥探查器会显示大量实例?的主要内容,如果未能解决你的问题,请参考以下文章

如何查看SQL Server2000执行过的SQL语句

为啥探查器看不到一种耗时的方法?

为啥我在探查器中获得的 C++ 运行时间不准确?

为啥 Pycharm 的检查器会抱怨“d = ”?

当我构建我的项目时,Visual Studio 2008 没有创建 .exe 文件。任何想法为啥?

为啥我可以从 char * const 值创建 char * 向量?