java - 使用 PermGen 空间或 roll-my-own intern 方法?

标签 java garbage-collection permgen string-interning

我正在编写一个编解码器来处理使用定制有线协议(protocol)通过 TCP 发送的消息。在解码过程中,我创建了一些 String小号,BigDecimal和日期。客户端-服务器访问模式意味着客户端发出请求然后解码数千个响应消息是很常见的,这导致大量重复 String小号,BigDecimal

因此我创建了一个 InternPool<T>类允许我实习每一类对象。在内部,池使用 WeakHashMap<T, WeakReference<T>> .例如:

InternPool<BigDecimal> pool = new InternPool<BigDecimal>();

...

// Read BigDecimal from in buffer and then intern.
BigDecimal quantity = pool.intern(readBigDecimal(in));

我的问题:我正在使用 InternPool对于 BigDecimal但我是否应该考虑将它用于 String 代替 Stringintern()方法,我相信它使用 PermGen 空间?使用 PermGen 空间有什么好处?

最佳答案

如果您已经有了这样一个 InternPool 类,它认为使用它比为字符串选择不同的实习方法更好。特别是因为 String.intern()似乎提供了比您实际需要的更有力的保证。您的目标是减少内存使用,因此实际上不需要在 JVM 的生命周期内进行完美的实习。

此外,我会使用 Google Collections MapMaker创建一个 InternPool 以避免重新创建轮子:

Map<BigDecimal,BigDecimal> bigDecimalPool = new MapMaker()
    .weakKeys()
    .weakValues()
    .expiration(1, TimeUnits.MINUTES)
    .makeComputingMap(
      new Function<BigDecimal, BigDecimal>() {
        public BigDecimal apply(BigDecimal value) {
          return value;
        }
      });

这将为您提供(正确实现的)弱键和值、线程安全、自动清除旧条目和一个非常简单的界面(一个简单、众所周知的 Map)。可以肯定的是,您还可以使用 Collections.immutableMap() 来包装它,以避免错误的代码干扰它。

关于java - 使用 PermGen 空间或 roll-my-own intern 方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2865026/

相关文章:

java - 无法从客户端应用程序调用 GWT-RPC

java,ByteBuffer从文件中解析数据

java - java中的中缀到后缀的转换

Java 小程序可排序列表

java - 为什么 java.lang.ref.Reference<T> 不实现 Supplier<T>?

android - 无法使用 LibGDX Net 在 Android 上下载 100mb 文件

java - 使用-XX :+PrintHeapAtGC?的GC日志中堆内存地址的含义

PermGen 空间中的 Java 类大小

java - 重新部署时出现 NetBeans/Glassfish 和 PermGen 空间错误(是的,仍然发生)

Java - 在堆上内联初始化字符串数组内存分配?