繁体   English   中英

我是否需要担心字符串常量池?

[英]Do I need to worry about the String Constant Pool?

我有一个非常庞大的Java应用程序 - 它需要大量不同的String对象。

我是否需要担心字符串常量池的内存和性能?

有什么方法可以看到游泳池在任何时候都有多大?

正如Mario所说,常量池只与intern()ed字符串相关,而且与java代码中的常量字符串相关(这些是隐式实现的)。

但是还有一个警告可能适用于您的情况: substring()方法将与原始String共享底层char[] 所以模式

  String large = ...                  // read 10k string
  String small = large.substring(...) // extrakt a few chars
  large = null;  // large String object no longer reachable,
                 // but 10k char[] still alive, as long as small lives

可能会导致意外的内存使用

如果它是对象的提要,那么除非你调用intern(),否则它们不会进入String常量池,据我所知。 实习字符串的内存消耗不是来自Heap,而是来自Perm Gen内存空间,因此如果您实施了很多字符串,应用程序将与OutOfMemory崩溃,即使剩下很多堆也是如此。

因此,除非您实习所有这些字符串,否则不应该关注它。 如果它成为一个问题,可以有自己的Map实现来存储这些字符串,所以你不使用内部机制。

我检查了intern()方法的实现,它是本机的,因此测量内存消耗或查看池的内容似乎并不简单。

如果内存不足,可以使用此标志来增加PermSize:

-XX:MaxPermSize=64m

我认为无论有无实习,都应该对您的应用进行分析。 然后,您将看到确切的效果。

我不相信有一种方法可以看到字符串常量池的大小。

我不知道程序究竟是什么,我只能建议您尝试将字符串用作流,并且不存储字符串作为整体。 也许你需要为你的应用程序做更多的抽象,并发明一个内存效率更高的中间表示?

在Java 1.7 substring()中 - 方法不再使用相同的char []而是将子字符串复制到新的数组中,即

public String substring(int beginIndex, int endIndex) {
        if (beginIndex < 0) {
            throw new StringIndexOutOfBoundsException(beginIndex);
        }
        if (endIndex > value.length) {
            throw new StringIndexOutOfBoundsException(endIndex);
        }
        int subLen = endIndex - beginIndex;
        if (subLen < 0) {
            throw new StringIndexOutOfBoundsException(subLen);
        }
        return ((beginIndex == 0) && (endIndex == value.length)) ? this
                : new String(value, beginIndex, subLen);
    }

如果beginIndex不为零或endIndex不等于char []数组的长度,则全部为String构造函数。

public String(char value[], int offset, int count) {
        if (offset < 0) {
            throw new StringIndexOutOfBoundsException(offset);
        }
        if (count < 0) {
            throw new StringIndexOutOfBoundsException(count);
        }
        // Note: offset or count might be near -1>>>1.
        if (offset > value.length - count) {
            throw new StringIndexOutOfBoundsException(offset + count);
        }
        this.value = Arrays.copyOfRange(value, offset, offset+count);
    }

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM