为什么我的Java堆有这么多字符[]

为什么我的Java堆有这么多字符[],java,performance,tomcat,memory-leaks,Java,Performance,Tomcat,Memory Leaks,我在Tomcat中有一个web应用程序,我在其中执行许多字符串操作(substring、indexof、trimming等)。我用jmap做了一个堆转储,并用VisualVM加载了它,我意识到我的堆内存使用量中有近50%是用char[], 为什么char[]会占用内存?我应该关心吗?它是否与字符串池有关?字符串在内部只是一个char[]和一些额外的数据。char[]表示字符数组,换句话说,它是一个逐字符保存字符串的数组。如果您做了大量的字符串处理,那么您的系统完全可能是带有字符数组的fileld

我在Tomcat中有一个web应用程序,我在其中执行许多字符串操作(substring、indexof、trimming等)。我用jmap做了一个堆转储,并用VisualVM加载了它,我意识到我的堆内存使用量中有近50%是用char[],
为什么char[]会占用内存?我应该关心吗?它是否与字符串池有关?

字符串在内部只是一个char[]和一些额外的数据。char[]表示字符数组,换句话说,它是一个逐字符保存字符串的数组。如果您做了大量的字符串处理,那么您的系统完全可能是带有字符数组的fileld


所以简而言之,没有什么值得关注的,除非你们的系统实际使用了更多的内存。在这种情况下,您可以查看是否有一些未清除的文件结构(哈希映射或相关)

811k的
char[]
对应800k的
String
s,所以是的,您的字符串太多了

如果内存泄漏(根据标记判断),那么很可能是
HashMap
中的字符串。您有800k个字符串实例、200k个哈希项实例和30k个映射。这可能意味着您的字符串保存在此缓存中,并且不会被删除。全局映射是导致内存泄漏的常见原因,您需要确保将它们从该缓存中逐出


由于没有对所有这些值进行GC编辑,您可以尝试分析对象图,以使用类似于的工具查看它们的内容。

我们可以查看一些代码吗?看起来您正在使用大量字符串-您是否检查了a
gc()
之后的结果?类似的事情:返回tiempo.replace(“años”).replace(“año”).replace(“año”).replace(“meses”),“”。replace(“mes”),“”。replace(“semanas”),“”。replace(“semanas”),“”。replace(“dias”),“”).更换(“直径”和“).trim()@NestorHernandezLoli,它将创建大量立即超出范围的临时对象。这里没有内存泄漏,垃圾收集器只是还没来得及清理它们。@NestorHernandezLoli从屏幕截图中我们可以看到你有很多散列图条目。您是否将字符串存储到映射中?@Andrey Chaschev,不,对于这个类,我没有使用HashMaps来保存stringsNote,探查器仅显示约90M在使用中;这一点也不多,垃圾收集器可能还没有足够的兴趣来清理它们。那么,char[]s是否有资格进行垃圾收集?如果您使用完它们,可以收集char[]s。问题是,您是否估计系统中应该有多少字符串?如果你期望有1000个字符串,而你有100000个以上的字符串,那么有些事情是错误的,但是如果你期望有这么多的字符串,那么有些事情是错误的。那么你希望有多少根弦呢?800k不是那么多。如何量化“太多字符串”?@SteveKuo,Nestor对此有问题::-)这可能是一个国家的垃圾场,当它还没有,但很快就会。我的答案是猜测,只是我见过很多这样的案例,我对此很有信心。