字符串是有问题的
基本上在Java中,String
引用(使用char[]
幕后的东西)将智慧主宰最业务应用程序的内存。它们的创建方式决定了它们在JVM中占用的内存量。
仅仅因为它们对于大多数业务应用程序来说如同数据类型一样非常重要,并且它们也是最需要内存的之一。这不仅仅是一个Java事物,String
数据类型在几乎每种语言和运行时库中占用大量内存,因为至少它们只是每个字符1个字节的数组,或者更糟糕的是(Unicode),它们是数组每个字符多个字节。
一旦纹上的Web应用程序,也有一个Oracle JDBC的依赖CPU的使用率,当我发现StringBuffer.append()
由多个数量级的占主导地位的CPU周期比所有其他方法调用结合,更不用说其他任何单一的方法调用。 JDBC驱动程序做了大量的操作,使用PreparedStatements
来处理所有事情。
你是什么人关心你无法控制,不能直接反正
你应该专注于什么是什么在你的控制,这是确保你不抱上引用长于你需要,而且你没有不必要的重复。 Java中的垃圾收集例程经过高度优化,如果您了解它们的算法如何工作,则可以确保您的程序以最佳方式运行这些算法。
Java堆内存不喜欢手动管理存储在其他语言中,这些规则并不适用
什么被认为内存泄漏其他语言是不一样的东西/根源为用Java的垃圾收集系统。
最有可能在Java内存中没有被泄漏的单个超级对象(其他环境中的悬挂参考)占用。
这是最有可能的,因为很多StringBuffer
/StringBuilder
对象不是第一instantantations适当大小,然后不得不自动增长char[]
阵列举行后续append()
通话较小的分配的。
由于垃圾收集器的范围和许多其他事情在运行时可能会有所不同,因此这些中间对象可能比垃圾收集器预期的时间长。
示例:垃圾收集器可能会决定有候选人,但由于它认为仍有大量内存需要处理,因此在该时间点刷新它们可能太昂贵了,它会一直等到内存压力升高。
垃圾收集器现在真的很好,但它不是魔术,如果你正在做退化的事情,它会导致它不能最佳工作。互联网上有大量关于所有JVM版本的垃圾收集器设置的文档。
这些未引用的对象可能尚未达到垃圾回收器认为需要它们从内存中清除它们的时间,或者可能存在其他对象(例如List
)所引用的引用你没有意识到仍然指向那个对象。这在Java中最常被称为泄漏,这是更具体的参考泄漏。
例:如果你知道你需要使用StringBuilder
与new StringBuilder(4096);
不是默认的,这就好比32,并立即开始创建的垃圾,可以代表很多时候你在想什么对象应该创造它来建立一个4K String
在尺寸上明智。
你可以发现有多少类型的对象用VisualVM实例化,这会告诉你你需要知道什么。不会有闪光灯指向一个类的单个实例,即“这是大内存消费者!”,即除非您正在阅读的某个char[]
只有一个实例大量的文件到,这也是不可能的,因为很多其他类在内部使用char[]
;然后你几乎已经知道了。
我没有看到OutOfMemoryError
任何提及,你可能没有在你的代码中的问题,垃圾收集系统,只是可能没有得到足够的压力下踢在和释放放置物体你认为它应该清理。什么你认为是一个问题可能不是,除非你的程序崩溃与OutOfMemoryError
。这不是C,C++,Objective-C或任何其他手动内存管理语言/运行库。你不能决定什么是在记忆中,或者不在你所期待的细节层面上。
我使用了一个分析器,它可以显示我分配对象的位置。我不知道VisualVM是否可以做到这一点,但它非常有用。我使用的是YourKit,但它不是免费的(但你可以获得一个eval许可证) – 2012-04-11 15:31:40
@PeterLawrey我实际上阅读了你前面写过的一个答案,你提到yourkit是你的第一选择,我确实查了它(因为你的建议总是很棒),但是它有点贵,我只是在学习。 – 2012-04-11 15:33:50
没有使用仪器代码的东西没有分析仪将能够指出哪个实例==你称为你的来源参考。 – 2012-04-11 16:05:04