美文网首页技术干货
Java String 内存大小

Java String 内存大小

作者: zoyanhui | 来源:发表于2020-03-18 20:03 被阅读0次

    As Picture Down:

        `java.lang.String`:  #bytes: 5722104  #instances: 238421
        5722104 / 238421 = 24,  **why?**
    
    222.jpg
    openjdk version "1.8.0_202"
    OpenJDK Runtime Environment (AdoptOpenJDK)(build 1.8.0_202-b08)
    OpenJDK 64-Bit Server VM (AdoptOpenJDK)(build 25.202-b08, mixed mode)
    
    jinfo -flag UseCompressedOops 22592
    -XX:+UseCompressedOops
    
    3.18.6-2.el7.centos.x86_64 #1 SMP Mon Oct 24 13:01:33 CST 2016 x86_64 x86_64 x86_64 GNU/Linux
    

    32Bit- Java 6

    String Object:

    First

    • a char array— thus a separate object— containing the actual characters; [4bytes, ) when no chars, it needs 4 at least
    • an integer offset into the array at which the string starts; 4bytes
    • the length of the string; 4bytes
    • another int for the cached calculation of the hash code. 4bytes

    Add Plus Object Header 8 bytes.

    4+4*3+8 = 24 bytes! This gives 24 bytes (which is a multiple of 8 so no "padding" bytes are needed so far).

    Second

    Underlying char array: 16 bytes.

    The empty char array: 12bytes

       4bytes: length
    
       8bytes: object header
      
       And, plus 4 bytes to padding.
    

    So, Actually, empty String needs 40bytes!

    More Deep

    1. 17 charactes String:

    char array: 17*2 = 34 bytes, plus empty char array 12bytes -> 46bytes.

    after Padding -> 48 bytes (a multiple of 8)

    So 48 + 24 =** 72 btyes!**

    when use C programming, it only 18bytes!

    2. SubString

    substring will share parent char array. So,

    • if you keep on to the parent string after creating the substring, then you will save memory overall;
    • if you throw away the parent string after creating the substring, then you will waste memory (if the substring is shorter than the parent).

    For example, in the following code:

    String str = "Some longish string...";
    str = str.substring(5, 4);
    

    It will waste memory, then we can create a new string instead.

    String str = "Some longish string...";
    str = new String(str.substring(5, 4));
    

    64Bit-Java8

    public final class String
        implements java.io.Serializable, Comparable<String>, CharSequence {
        /** The value is used for character storage. */
        private final char value[];
    
        /** Cache the hash code for the string */
        private int hash; // Default to 0
    

    String Object: (-XX:-UseCompressedOops): 32bytes

    • a char array— thus a separate object— containing the actual characters; [8bytes, ) when no chars, it needs 8 at least
    • another int for the cached calculation of the hash code. 4bytes
    • Mark work + Class ptr 16bytes
    • padding 4bytes

    String Object: (-XX:+UseCompressedOops): 24bytes

    • a char array— thus a separate object— containing the actual characters; [4bytes, ) when no chars, it needs 4 at least

    • another int for the cached calculation of the hash code. 4bytes

    • Mark work + Class ptr 8bytes + 4bytes

    • padding 4bytes
      所以上例中24bytes,是因为java8 64bit 环境中,使用 -XX:+UseCompressedOops.
      如果加上空数组的大小char[] value (16 bytes) 一共是40byte

    • SubString
      java 8 中substring已经改由System.arraycopy实现,不再共用同一个char[].

    /**
     * Allocates a new {@code String} that contains characters from a subarray
     * of the character array argument. The {@code offset} argument is the
     * index of the first character of the subarray and the {@code count}
     * argument specifies the length of the subarray. The contents of the
     * subarray are copied; subsequent modification of the character array does
     * not affect the newly created string.
     *
     * @param  value
     *         Array that is the source of characters
     *
     * @param  offset
     *         The initial offset
     *
     * @param  count
     *         The length
     *
     * @throws  IndexOutOfBoundsException
     *          If the {@code offset} and {@code count} arguments index
     *          characters outside the bounds of the {@code value} array
     */
    public String(char value[], int offset, int count) {
        if (offset < 0) {
            throw new StringIndexOutOfBoundsException(offset);
        }
        if (count <= 0) {
            if (count < 0) {
                throw new StringIndexOutOfBoundsException(count);
            }
            if (offset <= value.length) {
                this.value = "".value;
                return;
            }
        }
        // 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); // System.arraycopy
    }
    
    /**
     * Returns a string that is a substring of this string. The
     * substring begins with the character at the specified index and
     * extends to the end of this string. <p>
     * Examples:
     * <blockquote><pre>
     * "unhappy".substring(2) returns "happy"
     * "Harbison".substring(3) returns "bison"
     * "emptiness".substring(9) returns "" (an empty string)
     * </pre></blockquote>
     *
     * @param      beginIndex   the beginning index, inclusive.
     * @return     the specified substring.
     * @exception  IndexOutOfBoundsException  if
     *             {@code beginIndex} is negative or larger than the
     *             length of this {@code String} object.
     */
    public String substring(int beginIndex) {
        if (beginIndex < 0) {
            throw new StringIndexOutOfBoundsException(beginIndex);
        }
        int subLen = value.length - beginIndex;
        if (subLen < 0) {
            throw new StringIndexOutOfBoundsException(subLen);
        }
        return (beginIndex == 0) ? this : new String(value, beginIndex, subLen);
    }
    

    引用

    1.Memory usage of Java Strings and string-related objects

    相关文章

      网友评论

        本文标题:Java String 内存大小

        本文链接:https://www.haomeiwen.com/subject/uqncyhtx.html