Java字符串实习的替代方案 [英] Alternatives to Java string interning

查看:137
本文介绍了Java字符串实习的替代方案的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

由于Java的默认字符串实习有很多坏消息,我正在寻找替代方案。

Since Java's default string interning has got a lot of bad press, I am looking for an alternative.

你能否建议一个可以替代Java的API字符串实习?我的应用程序使用Java 6.我的要求主要是通过实习避免重复字符串。

Can you suggest an API which is a good alternative to Java string interning? My application uses Java 6. My requirement is mainly to avoid duplicate strings via interning.


  • 字符串实习生是通过本机方法实现的。并且C实现使用大约1k个条目的固定大小,并且对于大量字符串进行非常差的扩展。

  • Java 6在Perm gen中存储实习字符串。因此不是GC并且可能导致烫发错误。我知道这在java 7中已修复,但我无法升级到java 7.


  • 我的应用程序是一个服务器应用程序,堆大小为10-20G,适用于不同的部署。

  • 期间我们已经发现数以千计的字符串是重复的,我们可以通过避免存储重复的字符串来显着提高内存使用率。

  • 内存一直是我们的瓶颈,因此我们正在针对它而不是进行任何过早的优化。

推荐答案


字符串实习生是通过本机方法实现的。并且C实现使用大约1k个条目的固定大小,并且对于大量字符串的扩展非常差。

String intern is implemented via a native method. And the C implementation uses a fixed size of some 1k entries and scales very poorly for large number of strings.

对于许多字符串,它的扩展性很差千字符串。

It scales poorly for many thousand Strings.


Java 6在Perm gen中存储实习字符串。因此不是GC'd

Java 6 stores interned strings in Perm gen. And therefore are not GC'd

它会在清理烫发时被清理掉,这种情况并不常见,但可能意味着如果你不增加它,你就达到了这个空间的最大值。

It will be cleaned up when the perm gen is cleaned up which is not often but it can mean you reach the maximum of this space if you don't increase it.


我的应用程序是堆大小为10-20G的服务器应用程序对于不同的部署。

My application is a server app with heap size of 10-20G for different deployments.

我建议你考虑使用off heap memory。我在off heap内存中有500 GB,在一个应用程序中有大约1 GB的堆。它在所有情况下都没有用,但值得考虑。

I suggest you consider using off heap memory. I have 500 GB in off heap memory and about 1 GB in heap in one application. It isn't useful in all cases but worth considering.


在分析过程中,我们发现数千个字符串的数据是重复的,我们可以通过避免存储重复的字符串来显着改善内存使用。

During profiling we have figured that hundrends of thousands of string are duplicates and we can significantly improve the memory usage by avoiding storing duplicate strings.

为此,我使用了一个简单的String数组。这是非常轻的权重,您可以轻松控制存储的字符串的上限。

For this I have used a simple array of String. This is very light weight and you can control the upper bound of Strings stored easily.

这是一个通用内部的例子。

Here is an example of generic interner.

class Interner<T> {
    private final T[] cache;

    @SuppressWarnings("unchecked")
    public Interner(int primeSize) {
        cache = (T[]) new Object[primeSize];
    }

    public T intern(T t) {
        int hash = Math.abs(t.hashCode() % cache.length);
        T t2 = cache[hash];
        if (t2 != null && t.equals(t2))
            return t2;
        cache[hash] = t;
        return t;
    }
}

此缓存的兴趣属性是不是这不是线程安全的问题。

An interest property of this cache is it doesn't matter that its not thread safe.

对于额外的速度你可以使用2大小和位掩码的功率,但它更复杂,可能无法很好地工作取决于你的hashCodes是如何计算的。

For extra speed you can use a power of 2 size and a bit mask, but its more complicated and may not work very well depending on how your hashCodes are calculated.

这篇关于Java字符串实习的替代方案的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆