当前位置:网站首页>JVM memory and garbage collection -4-string

JVM memory and garbage collection -4-string

2022-07-08 01:58:00 xcrj

String definition

executive summary

  1. String By final modification public final class String
  2. String Member attribute value The array is final modification ,jdk8private final char value[];jdk9private final byte[] value;
  3. final A modifier class means that it cannot be inherited
  4. final The decorated member attribute indicates that it can only be initialized 1 Time
  5. Find out jdk8 Use private final char value[]; Store characters ,jdk9=+ Use private final byte[] value; private final byte coder; Store characters
  6. jdk9=+ This design String Why : Quote most String It's actually Latin-1,Latin1 yes ISO-8859-1 Alias occupation of 1byte,char Occupy 2byte, use char Storage wastes space
  7. jdk9=+, If the character is Latin-1, Use 1byte Storage , Otherwise, use 2byte Storage (coder=LATIN1 or UTF16)

jdk8

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

    /** use serialVersionUID from JDK 1.0.2 for interoperability */
    private static final long serialVersionUID = -6849794470754667710L;

jdk9

public final class String
    implements java.io.Serializable, Comparable<String>, CharSequence {
    

    /** * The value is used for character storage. * * @implNote This field is trusted by the VM, and is a subject to * constant folding if String instance is constant. Overwriting this * field after construction will cause problems. * * Additionally, it is marked with {@link Stable} to trust the contents * of the array. No other facility in JDK provides this functionality (yet). * {@link Stable} is safe here, because value is never null. */
    @Stable
    private final byte[] value;

    /** * The identifier of the encoding used to encode the bytes in * {@code value}. The supported values in this implementation are * * LATIN1 * UTF16 * * @implNote This field is trusted by the VM, and is a subject to * constant folding if String instance is constant. Overwriting this * field after construction will cause problems. */
    private final byte coder;

    /** Cache the hash code for the string */
    private int hash; // Default to 0

    /** use serialVersionUID from JDK 1.0.2 for interoperability */
    private static final long serialVersionUID = -6849794470754667710L;

String properties

String Immutability

executive summary

  1. String By final modification public final class String
  2. String Member attribute value The array is final modification jdk8private final char value[];jdk9private final byte[] value;
  3. Parameter passing reference variables are copies of values , The re assignment of this reference variable inside the method will not affect the reference variable outside the method ; Method internal operation refers to the member variable of the variable , Method external reference variables will be affected

Code

package xcrj;

/* * String Immutability  *  result  * 1 It's about hashcode=2 It's about hashcode=3 Situated hashcode * */
public class VMStringFinal {
    
    public static void main(String[] args) {
    
        String str = "xcrj";
        System.out.println("1》" + str);
        System.out.println("1》" + str.hashCode());
        VMStringFinal vmsp = new VMStringFinal();
        vmsp.refTrans(str);
        //  The referenced value is passed ,str The value of will not change , Still xcrj
        System.out.println("2》" + str);
        System.out.println("2》" + str.hashCode());
    }

    public void refTrans(String str) {
    
        System.out.println("3》" + str);
        System.out.println("3》" + str.hashCode());
        str = "xcrj2";
        System.out.println("4》" + str);
        System.out.println("4》" + str.hashCode());
    }
}

result

1》xcrj
1》3673699
3》xcrj
3》3673699
4》xcrj2
4》113884719
2》xcrj
2》3673699

String constant pool structure

executive summary

  • The string constant pool is fixed Hashtable( Similar data structures “ Hash ( Chain address )”)
  • jdk6 The default fixed size of string constant pool is 1009;jdk7=+ The default fixed size of string constant pool is 60013
  • The fixed size setting is too small, resulting in more first conflicts ,intern() Method performance degradation

Hashtable- Hash ( Chain address )
 Insert picture description here
Code

package xcrj;

/* *  First  -XX:StringTableSize=1009 *  Be careful   Minimum 1009 * */
public class VMStringPoolSize {
    
    public static void main(String[] args) {
    
        try {
    
            Thread.sleep(1000000);
        } catch (InterruptedException e) {
    
            e.printStackTrace();
        }
    }
}

command

#  compile 
javac -d D:\workspace\idea\JVMDemo\blog\target\classes\ -encoding UTF-8 VMStringPoolSize.java
#  function 
java -XX:StringTableSize=1009 -classpath D:\workspace\idea\JVMDemo\blog\target\classes\ xcrj.VMStringPoolSize

result
 Insert picture description here

String memory

jdk6

The string constant pool is located in the method area / Forever in generation

jdk7

The string constant pool is located in the heap
Reason for changing position :GC For method area / The recovery frequency of permanent generation is very low , However, string constants are frequently used

String creation

Literal

Code

String str="xcrj";

Introduce

  • Create anonymous in the string constant pool String object 》 The reference is assigned to str

new String

Code

String str=new String("xcrj");

Introduce

  1. labelA: Create anonymous in the string constant pool String object , hold value Array attribute
  2. labelB: Heap creation String object , Internal holding value Array attribute
  3. value Array reference assignment

Example

Code

package xcrj;

/* *  String constant decompile view  * */
public class VMStringConstPool {
    
    public static void main(String[] args) {
    
        String str = "xcrj";
        String str1 = "xcrj1";
        String str2 = "xcrj2";
    }
}

command

#  compile 
javac -d D:\workspace\idea\JVMDemo\blog\target\classes\ VMStringConstPool.java
#  Decompile 
javap -classpath D:\workspace\idea\JVMDemo\blog\target\classes\ -v xcrj.VMStringConstPool

result
 Insert picture description here
 Insert picture description here

String manipulation

toString()

executive summary

  • Of each class toString() The internal implementation of the method is different
  • String object toString() Methods the internal return this;
  • StringBuilder object toString() Methods the internal new String(value, 0, count);
  • Object object toString() Methods the internal return getClass().getName() + "@" + Integer.toHexString(hashCode()); Namely String str="getClass().getName() + "@" + Integer.toHexString(hashCode())";

Code

package xcrj;

public class VMStringToString {
    
    public static void main(String[] args) {
    
        Object obj = new Object();
        VMStringToString vmsts = new VMStringToString();
        vmsts.toStr(obj);
    }

    public void toStr(Object obj) {
    
        String str = obj.toString();
        String str1 = obj.toString();
        // false
        System.out.println(str == str1);
        String strIntern = str.intern();
        String str1Intern = str1.intern();
        // true
        System.out.println(strIntern == str1Intern);
    }
}

Instructions

#  compile 
javac -d D:\workspace\idea\JVMDemo\blog\target\classes\ -encoding UTF-8 VMStringToString.java
#  Decompile 
javap -classpath D:\workspace\idea\JVMDemo\blog\target\classes\ -v xcrj.VMStringToString

Decompile
 Insert picture description here

Splicing

executive summary

  • String literals are constants
  • String literals are first placed in the string constant pool
  • There is no string with the same content in the string constant pool
  • The splicing results of string constants and string constants are in the string constant pool ( Compile time optimization is responsible )
  • String splicing as long as there is a string variable in it, the result is in the heap (StringBuilder be responsible for )

Be careful - String concatenates at least one string variable

  • String literals are objects in the string constant pool
  • new String() object ( No, new String() There is no such object )
  • StringBuilder object
  • StringBuilder object toString() Methods the internal new String(value, 0, count);( from StringBuilder After the object splicing is completed, the last call )

Code

package xcrj;

/* *  String splicing  * */
public class VMStringBuilder {
    
    public static void main(String[] args) {
    
        //  String constant concatenation 
        String str = "xc" + "rj";
        //  String constant concatenation 
        final String str1 = "xc";
        final String str2 = "rj";
        String str3 = str1 + str2;
        // true
        System.out.println(str == str3);
        //  String variable splicing 
        String str4 = "xc";
        String str5 = str + "rj";
        // false
        System.out.println(str == str5);
    }
}

Instructions

#  compile 
javac -d D:\workspace\idea\JVMDemo\blog\target\classes\ -encoding UTF-8 VMStringBuilder.java
#  Decompile 
javap -classpath D:\workspace\idea\JVMDemo\blog\target\classes\ -v xcrj.VMStringBuilder

Decompile
 Insert picture description here

analysis

  • The splicing of string constants will be spliced together at compile time 0: ldc #2 // String xcrj 3: ldc #2 // String xcrj
  • At least one string variable is spliced by StringBuilder The object is responsible for
  • StringBuilder It is responsible for calling toString() Method
  • StringBuildertoString() Method will generate 1 Objects are stored in LV in astore

intern()

executive summary

  • Make sure that there is only one copy of the string in memory
  • Returns a reference to a string constant in the string constant pool
  • Pseudo code
if ( There is this string constant in the string constant pool ) {
	 Returns a reference to this string constant 
} else {
	 Add this string constant to the string constant pool 
	 Returns a reference to this string constant 
}

Code

package xcrj;

public class VMStringIntern {
    
    public static void main(String[] args) {
    
        String str = "xcrj";
        String strIntern = str.intern();
        // true
        System.out.println(str == strIntern);

        String str1 = new String("xcrj1");
        String str1Const = "xcrj1";
        String str1Intern = str1.intern();
        // false
        System.out.println(str1 == str1Intern);
        // true
        System.out.println(str1Const == str1Intern);

        Object obj = new Object();
        String str2 = obj.toString();
        String str2Intern = str2.intern();
        // true
        System.out.println(str2 == str2Intern);

        StringBuilder sb = new StringBuilder();
        sb.append("xcrj2");
        String str3 = sb.toString();
        String str3Intern = str3.intern();
        // fasle
        System.out.println(str3 == str3Intern);
    }
}

tuning

java8/StringBuilder

executive summary

  • At least 1 The splicing of string variables consists of StringBuilder be responsible for
  • structure StringBuilder When using StringBuilder builder=new StringBuilder(capacity), Give the appropriate initial capacity ( Inside char[] size , The nonparametric construction is 16)
  • Avoid repeated expansion ( Old capacity *2+2): Create a new char[]》 Value copy 》 Discard old char[]
  • StringBuilder object toString() Methods the internal new String(value, 0, count);

Source code

abstract class AbstractStringBuilder implements Appendable, CharSequence {
    
    /** * The value is used for character storage. */
    char[] value;

    /** * The count is the number of characters used. */
    int count;
	
	/** * For positive values of {@code minimumCapacity}, this method * behaves like {@code ensureCapacity}, however it is never * synchronized. * If {@code minimumCapacity} is non positive due to numeric * overflow, this method throws {@code OutOfMemoryError}. */
    private void ensureCapacityInternal(int minimumCapacity) {
    
        // overflow-conscious code
        if (minimumCapacity - value.length > 0) {
    
            value = Arrays.copyOf(value,
                    newCapacity(minimumCapacity));
        }
    }	
	
	/** * Returns a capacity at least as large as the given minimum capacity. * Returns the current capacity increased by the same amount + 2 if * that suffices. * Will not return a capacity greater than {@code MAX_ARRAY_SIZE} * unless the given minimum capacity is greater than that. * * @param minCapacity the desired minimum capacity * @throws OutOfMemoryError if minCapacity is less than zero or * greater than Integer.MAX_VALUE */
    private int newCapacity(int minCapacity) {
    
        // overflow-conscious code
        int newCapacity = (value.length << 1) + 2;
        if (newCapacity - minCapacity < 0) {
    
            newCapacity = minCapacity;
        }
        return (newCapacity <= 0 || MAX_ARRAY_SIZE - newCapacity < 0)
            ? hugeCapacity(minCapacity)
            : newCapacity;
    }
    
    @Override
    public String toString() {
    
        // Create a copy, don't share the array
        return new String(value, 0, count);
    }

final Modifier

executive summary

  • Try to have final, It will be optimized at compile time

String splicing intern() Optimize

executive summary

  • jdk6: The string constant pool is located in the method area / Forever in generation
  • jdk7=+: The string constant pool is located in the heap
  • jdk7=+: String splicing result call intern() Methods exist optimization (StringBuilder Object was last called toString() Method to create the object A In the heap area , The string constant pool is also in the heap , Call again intern() Method directly converts the object A The reference to returns )
    Code
package xcrj;

public class VMStringInternjdk {
    
    public static void main(String[] args) {
    
        String str = new String("xcrj");
        String strIntern = str.intern();
        String str1 = "xcrj";
        /* * jdk6: The string constant pool is located in the method area / Forever in generation  * jdk7=+: The string constant pool is located in the heap  * jdk6/7/8  All are false * */
        System.out.println(str == str1);
        /* * jdk6: The string constant pool is located in the method area / Forever in generation  * jdk7=+: The string constant pool is located in the heap  * jdk6/7/8  All are true * */
        System.out.println(strIntern == str1);

        String strss = new String("xcrjxcrj");
        String strss1 = new String("xcrjxcrj");
        // false
        System.out.println(strss == strss1);
        String strssIntern = strss.intern();
        String strss1Intern = strss1.intern();
        // false
        System.out.println(strss == strss1);
        // true
        System.out.println(strssIntern == strss1Intern);

        String str2 = new String("xcrj2") + new String("xcrj2");
        str2.intern();
        String str3 = "xcrj2xcrj2";
        /* * jdk6: The string constant pool is located in the method area / Forever in generation  * jdk7=+: The string constant pool is located in the heap  * jdk6: yes false * jdk7/8  All are true * */
        System.out.println(str2 == str3);

        String str4 = new String("xcrj4") + "xcrj4";
        str4.intern();
        String str5 = "xcrj4xcrj4";
        /* * jdk6: The string constant pool is located in the method area / Forever in generation  * jdk7=+: The string constant pool is located in the heap  * jdk6: yes false * jdk7/8  All are true * */
        System.out.println(str4 == str5);
    }
}

Parameters

classification Parameters effect Suggest
String-XX:StringTableSizejdk6 The default fixed size of string constant pool is 1009;jdk7=+ The default fixed size of string constant pool is 60013 no

Interview questions

  1. new String(“xcrj”) Several objects are created ?
    answer :2 Objects
  2. new String(“xc”)+new String(“rj”) Several objects are created ?
    answer :6 Objects
package xcrj;

/* *  Interview questions  * */
public class VMStringFace {
    
    public static void main(String[] args) {
    
        VMStringFace vmsf = new VMStringFace();
        vmsf.face1();
        vmsf.face2();
    }

    /* * new String("xcrj")  Several objects are created ? *  in total 2 Objects : *  There are... In the string constant pool 1 An anonymous object  *  There are 1 Objects  * */
    public void face1() {
    
        String str = new String("xcrj");
    }

    /* * new String("xc")+new String("rj") Several objects are created ? *  in total 6 Objects : *  There are... In the string constant pool 2 An anonymous object  *  There are 2 Objects  * StringBuilder object  * StringBuilder After splicing objects toString() Will be created in the heap 1 Objects  * */
    public void face2() {
    
        String str = new String("xc") + new String("rj");
    }
}

Decompile
 Insert picture description here

原网站

版权声明
本文为[xcrj]所创,转载请带上原文链接,感谢
https://yzsam.com/2022/02/202202130541456567.html