java垃圾收集和临时对象

Taz*_*Taz 6 java garbage-collection

我是一名c ++开发人员,但我最近做了一点Java.我正在工作的这个项目是由开发人员完成的,很久以后我就一直在寻找他正在通过做奇怪事情来解决垃圾收集问题的事情.

Case和point他实现了自己的字符串类,以避免GC减速

应用程序的这一部分采用大型二进制文件格式并将其导出到csv.这意味着为文件中的每一行构建一个字符串(数百万).为了避免这些临时字符串对象,他创建了一个字符串类,它只有一个重复使用的大字节数组.

/**
 HACK
     A Quick and Dirty string builder implementation optimized for GC.
     Using String.format causes the application grind to a halt when
     more than a couple of string operations are performed due to the number of
     temporary objects allocated while formatting strings for drawing or logging.    
*/
Run Code Online (Sandbox Code Playgroud)

这实际上有帮助吗?这真的需要吗?这比仅仅在循环外声明一个String对象并将其设置在循环中更好吗?

该应用程序还有一个哈希映射,包含值的双精度数.地图中的键是相当静态的,但值经常变化.由于害怕GC上双打,他将myDouble类用作hashmap的值

/**
 *  This is a Mutable Double Wrapper class created to avoid GC issues
 *
 */
public class MyDouble implements Serializable {
    /**
     * 
     */
    private static final long serialVersionUID = C.SERIAL_VERSION_UID;
    public double d;

    public MyDouble(double d) {
        this.d = d;
    }
}
Run Code Online (Sandbox Code Playgroud)

这很疯狂,完全没必要......对吗?

Nic*_*olt 3

确实,字符串连接可能是 Java 中的瓶颈,因为Strings 是不可变的。这意味着每次串联都会创建一个新的String,除非之前创建了匹配项String并因此位于字符串池中(请参阅string interning)。无论哪种方式,它肯定会导致问题。

然而,您的前任并不是第一个遇到这种情况的人,处理StringJava 中连接多个 s 的标准方法是使用StringBuilder

当 a double(或任何与此相关的原语)用作局部变量时,它会保留在堆栈中,并且它占用的内存会与堆栈帧一起释放(不确定它们是否受到 GC 的影响或由 JVM 处理)当它运行时)。但是,如果该double字段是对象上的字段,则它将存储在堆上,并且当包含它的对象被收集时将被收集。

在不了解这些double值如何使用的情况下,很难确定,但很可能是这些值的使用Map增加了 GC 负载。

总而言之,是的,恕我直言,正如您所说,这当然是“疯狂且完全没有必要”。这些过早的优化只会使代码库变得复杂,使其更容易出现错误,并使未来的维护更加困难。黄金法则实际上应该始终是:构建最简单、可行的东西,对其进行分析,然后进行优化。