性能调优基础篇之内存中大量重复String对象

来源:互联网 发布:sql常用查询语句 编辑:程序博客网 时间:2024/06/09 20:36

首先介绍一个string的 intern() 方法:

大意为,当这个string 没有在常量池时,会把这个String对象加入到常量池, 否则直接重常量池中返回该对象的引用

      /**
     * Returns a canonical representation for the string object.
     * <p>
     * A pool of strings, initially empty, is maintained privately by the
     * class <code>String</code>.
     * <p>
     * When the intern method is invoked, if the pool already contains a
     * string equal to this <code>String</code> object as determined by
     * the {@link #equals(Object)} method, then the string from the pool is
     * returned. Otherwise, this <code>String</code> object is added to the
     * pool and a reference to this <code>String</code> object is returned.
     * <p>
     * It follows that for any two strings <code>s</code> and <code>t</code>,
     * <code>s.intern()&nbsp;==&nbsp;t.intern()</code> is <code>true</code>
     * if and only if <code>s.equals(t)</code> is <code>true</code>.
     * <p>
     * All literal strings and string-valued constant expressions are
     * interned. String literals are defined in section 3.10.5 of the
     * <cite>The Java&trade; Language Specification</cite>.
     *
     * @return  a string that has the same contents as this string, but is
     *          guaranteed to be from a pool of unique strings.
     */
    public native String intern();


应用场景:当用大量重复String对象构建缓存时{这些String可能来自DB或是文件流}。应用.internal方法能极大的提高内存使用率


/** * Created with IntelliJ IDEA. * User: jianjun.yu * Date: 14-8-11 * Time: 下午5:39 * To change this template use File | Settings | File Templates. */public class HadIntern {    public static void main(String[] args) throws InterruptedException {        Map<Integer, String > map = Maps.newHashMap();        for(Integer i = 0; i < 10000; i++){            map.put(i, new String("aaaaaaaaaaaaaaa").intern());        }        Thread.sleep(1000000);    }}

查看String对象实例数:1299

[root@jjy /home/q/document]# jmap -histo:live 26200 | grep String
  14:          1299          31176  java.lang.String
  36:            55           2008  [Ljava.lang.String;
 119:             2             64  java.lang.StringCoding$StringEncoder
 146:             1             32  java.lang.StringCoding$StringDecoder
 181:             1             24  java.lang.StringBuilder
 210:             1             16  java.lang.String$CaseInsensitiveComparator


</pre><pre name="code" class="java">/** * Created with IntelliJ IDEA. * User: jianjun.yu * Date: 14-8-11 * Time: 下午5:38 * To change this template use File | Settings | File Templates. */public class NoIntern {    public static void main(String[] args) throws InterruptedException {        Map<Integer, String > map = Maps.newHashMap();        for(Integer i = 0; i < 10000; i++){            map.put(i, new String("aaaaaaaaaaaaaaa"));        }        Thread.sleep(1000000);    }}

查看String 对象实例数: 12310
[root@jjy /home/q/document]# jmap -histo:live 26127 | grep String
  10:         12310         295440  java.lang.String
  22:           286           6864  java.lang.StringBuilder
  35:            71           2496  [Ljava.lang.String;
  49:            68           1632  java.lang.StringBuffer
 117:             2             96  java.util.StringTokenizer
 145:             2             64  java.lang.StringCoding$StringEncoder
 180:             1             32  java.lang.StringCoding$StringDecoder
 257:             1             16  java.lang.String$CaseInsensitiveComparator

当然这里例子比较极端,10000个相同string常量值。

该方法的优化并不适合与任何情况, 只适合有大量相同String的情况

0 0
原创粉丝点击