Java中单次使用的大字符串用new String()比双引号更省内存吗?
问题结论
第二段代码不能节省内存,反而会额外消耗更多内存,是典型的优化误区。
原因解释
只要代码中出现双引号包裹的字符串字面量,无论你是直接赋值给String变量,还是作为new String()的入参使用,类加载阶段这个字面量都会被自动加入字符串常量池:
- Code-1的写法只会在常量池生成1份字符串实例,每次调用
run()直接复用该实例。 - Code-2的写法除了常量池的1份实例外,每次调用
run()都会在堆上额外创建1份内容完全相同的String实例,同一份字符串内容存了2份,明显多占内存。
如果确实要避免大字符串常驻常量池,正确的做法是不要把大字符串写为代码里的字面量,比如把内容存到外部配置文件运行时读取、或者用char数组构造字符串即可。
判断两种写法效率需要额外考虑的因素
- 方法实际调用频率:如果
run()调用频率极高,Code-1直接复用常量池实例,不需要每次创建新对象,内存和性能表现远好于Code-2;如果调用频率极低,两种写法差异可以忽略。 - JDK版本差异:JDK6及更早版本字符串常量池放在永久代,常驻内存基本不会被GC;JDK7+版本字符串常量池移到堆区,只要对应类被卸载,常量池的字符串也可以被GC回收。
- 类的生命周期:如果
Engine类是临时加载的动态类,用完就会被类加载器卸载,那常量池的字符串也会跟着被回收,完全不需要刻意用new的写法。 - 字符串后续使用场景:如果该字符串后续会被频繁用作哈希表key、字符串相等判断等场景,常量池的字符串复用度更高,性能表现更好。
内容的提问来源于stack exchange,提问作者stux_kill
相关产品推荐
相关产品推荐

