是Java的字符串实习生一个轻量级?(Is Java's String Intern a f

2019-06-25 17:45发布

难道Java的字符串内存池的实现遵循轻量级的模式?

为什么我有这样的疑问是,我看到有参与实习生没有外在状态。 在GoF的我看了,应该有内在和外在状态之间的适当平衡。 但在实习生的一切是内在的。

或者我们应该说有相对于属性没有严格的规则和公正的分享对象以减少内存就足以称之为一个轻量级。

请帮助我了解。

Answer 1:

是的String.intern()执行如下的轻量级的模式。

正如javadoc的说

返回字符串对象的规范表示。 串,初始为空池,由String类私人维护。

当调用实习生方法中,如果池已包含一个字符串等于由equals(Object)方法来确定此字符串对象,然后从池中字符串被返回。 否则,这个String对象添加到池中,并返回此String对象的引用。

由此可见,对于任何两个字符串s和t,s.intern()== t.intern()为真当且仅当s.equals(t)是正确的。

所有的文字字符串和字符串值常量表达式拘留。 字符串文字在Java语言规范的§3.10.5定义

该内部化字符串驻留在“彼尔姆根”的空间和对返回的字符串对象.intern()您可以使用运营商==因为.intern()始终返回相等的值相同的对象。

然后记得.intern()方法不会产生泄漏,因为今天的JVM能够垃圾池。

尝试阅读这篇文章了。



Answer 2:

不论实习的,Java的String通过共享利用轻量级图案char[]字符串和从它派生经由之间substring和类似方法调用。 这有不利的一面,但如果你把一个巨大的串小串,巨大char[]将没有资格进行垃圾回收。

注意:作为OpenJDK的版本1.7.0_06以上已经过时:代码被改变,使得char[]不再实例之间共享。 substring()创建新的数组。



Answer 3:

你已经正确识别这两个实习和飞锤都是基于同样的想法:缓存和共享共同的状态。

随着飞锤,在极端情况下,当有存储没有外在的状态,只有指针到内在状态保持。 再有就是没有必要的外在状态,甚至是一个对象,指针本身可以是外在的状态。 这时候,飞锤已成为实习。

无论是实习“真”是或不是一种飞锤的是刚刚超过定义的辩论。 最重要的是一个如何可以视为是其他的特殊情况的了解,所以你是好。



Answer 4:

就像其他人所指出的,中的String.intern()是所有关于缓存。 它返回参考已存储的字符串在游泳池文字。 通过这种方式,在某种程度上类似于轻量级的模式,因为它使用从而降低内存消耗现有的对象和更高的性能(虽然实习生在字符串池中查找自身的性能开销太大)。 因此,这两个可以出现类似,但他们实际上并非如此。



Answer 5:

不,共享对象以减少内存不足以称之为轻量级。 换句话说,高速缓存是不会自动飞摆图案。

我认为这将是公平地说,轻量级缓存是一种特殊形式,即部分缓存; 但千万注意GoF的书不使用的话“缓存”或“高速缓存”中的轻量级章(虽然条款以前面和后面的章节,门面和代理分别使用)任何地方。

一对夫妇在此线程的意见是值得重复,因为他们回答简洁的整体问题。

  • 如果你的对象没有外在的环境,然后你只是缓存。 整个原因享元模式甚至有用的定义,是人们常常忘记他们至少可以缓存,它独立于环境和分享对象的一部分。

    --CS

  • 飞锤是分享对象的内部。 实习只是缓存整个对象。

    --Marko Topolnik

但是,让我们比较两个字符串实习到GoF的定义(197页)的标准。

应用在以下所有的都是真享元模式:

  • 应用程序使用了大量的对象。
  • 存储成本,因为对象的绝对数量都高。
  • 大多数对象状态可以制成外在的。
  • 对象的许多基团可通过相对少的共享对象更换一次外在状态被去除。
  • 该应用程序不依赖于对象的身份。 由于轻量级的对象可以被共享,身份测试将用于概念不同的对象返回true。
  1. 显然,许多应用程序都使用了大量的弦乐,所以这个标准通过。
  2. 将字符串存储是昂贵的,至少比原始类型,让我们给这个标准一通。
  3. 这里我们得到绊倒了: 没有任何一个字符串的状态是由外在的。 这个标准将失败。
  4. 如果我们慷慨,忽略有关外在状态的一部分,我们可以给这个标准一通为好,因为字符串确实会被重复使用。
  5. 任何人谁是有史以来使用==在Java中比较字符串知道不依赖于对象的身份,所以这个标准通过。

那么4/5通过的标准是很不错吧? 难道不应该足够地说,实习/缓存和轻量级是一样的吗? 无:相似=相同。 所有在GoF的报价的话强调的是他们的,不是我的。 有自然的强烈愿望标注为许多实现尽可能与GoF模式的名字,因为这样做借给合法性的实现。 (最恶劣的情况是工厂模式,您可以轻松地找到标注每一种造物代码想象,但我离题了。)如果模式不准备持有至其公布的定义,它们重叠而失去意义,击败了很大一部分他们的目的(常用的词汇)。

最后,让我们来分析轻量级章的第一句话:什么GoF的定义为轻量级模式的意图

使用共享,以有效支持细粒度对象的大量涌现。

我认为,没有外在状态的对象不是细粒,而是相反; 所以这里是缓存建议意图 :使用缓存技术有效地支持大量的粗粒度的对象。

很明显,有字符串之间的相似度实习/缓存和享元模式; 但他们是不一样的。



Answer 6:

飞锤是分享对象immmutables内部。 实习只是缓存整个对象。



文章来源: Is Java's String Intern a flyweight?