One: In Java, there are six different places where data can be stored:
1. Register (Register). This is the fastest storage area because it is located in a different location from the other store-the inside of the processor. However, the number of registers is extremely limited, so the registers are allocated by the compiler on demand. You cannot directly control or feel any sign of register presence in the program.
------The fastest storage area, which is allocated by the compiler on demand, is beyond our control in the program.
2. Stacks (Stack). is located in Universal RAM, but it can be supported from the processor with its "stack pointer". If the stack pointer moves down, the new memory is allocated, and if you move up, the memory is freed. This is a fast and efficient method of allocating storage, second only to registers. When you create a program, the Java compiler must know the exact size and lifecycle of all the data stored in the stack, because it must generate the appropriate code to move the stack pointer up and down. This constraint limits the flexibility of the program, so while some Java data is stored on the stack-especially object references-the Java object does not store it.
------A reference to an array of variable data and objects of the underlying type, but the object itself is not stored in the stack, but is stored in the heap (the new object) or in a constant pool (the string constant object is stored in a constant pool)
3. Heap. A universal memory pool (also available in RAM) for storing so Java objects. The benefit of a heap that differs from the stack is that the compiler does not need to know how many storage areas to allocate from the heap, or how long the stored data survives in the heap. Therefore, there is great flexibility in allocating storage in the heap. When you need to create an object, you only need new to write a simple line of code, and when you execute this line of code, it will be automatically stored in the heap allocation. Of course, for this flexibility you have to pay the code accordingly. Storage allocation with heaps takes more time than storage storage with the stack.
------to store all new objects.
4. Static storage (storage). "Static" here means "in a fixed position". The data stored in the static store that persists while the program is running. You can use the keyword static to identify a particular element of an object that is static, but the Java object itself never resides in a static storage space.
------to store static members (statically defined)
5. Constant storage (constant storage). Constant values are usually stored directly inside the program code, and it is safe to do so because they are never changed. Sometimes, in an embedded system, the constants themselves are separated from the rest, so in this case, you can choose to place them in ROM
------Storing string constants and basic type constants (public static final)
6. Non-RAM storage. If the data is completely outside of the program, it can be free from any control of the program and can exist when the program is not running.
------hard disk, such as permanent storage space for speed, has the following relationship:
Registers > Stacks > Heaps > Other
Here we are primarily concerned with stacks, heaps, and constant pools, which can be shared for objects in stacks and constant pools, and not for objects in the heap.
The data size and life cycle in the stack can be determined, and the data disappears when no references point to the data. The garbage collector is responsible for the collection of objects in the heap, so the size and life cycle do not need to be determined and have great flexibility.
For strings: References to their objects are stored in the stack, and if the compilation period has been created (defined directly in double quotes), it is stored in a constant pool, which is stored in the heap if the run-time (new) is determined. For a string equal to equals, there is always only one copy in the constant pool, with multiple copies in the heap.
Code like this: Java code
String S1 = "China";
String s2 = "China";
String s3 = "China";
String ss1 = new String ("China");
String ss2 = new String ("China");
String ss3 = new String ("China");
Explain here that for a string to be generated by new (assuming "China"), the constant pool is first searched for whether the "China" object is already in place, and if none is created in the constant pool, then a copy object of this "China" object in the constant pool is then created in the heap.
That's the way to interview: string s = new string ("xyz"), how many objects are produced?
one or two of them. If there is no "xyz" in a constant pool, it is two. If there is "XYZ" in the original constant pool, it is one.
For variables and constants of the underlying type: variables and references are stored in the stack, and constants are stored in the constant pool.
Code like this: Java code
int i1 = 9;
int i2 = 9;
int i3 = 9;
public static final int INT1 = 9;
public static final int INT2 = 9;
public static final int INT3 = 9;
For member variables and local variables: member variables are external to the method, variables defined internally by the class;
A local variable is a variable defined inside a method or statement block. Local variables must be initialized. The formal parameter is a local variable, and the data for the local variable exists in the stack memory. Local variables in the stack memory disappear as the method disappears. Member variables are stored in objects in the heap and are collected by the garbage collector.
Code like this: Java code
Class BirthDate {
private int day;
private int month;
private int year;
Public BirthDate (int d, int m, int y) {
Day = D;
month = m;
Year = y;
}
Omit the Get,set method ...
}
public class test{
public static void Main (String args[]) {
int date = 9;
Test test = new test ();
Test.change (date);
BirthDate d1= New BirthDate (7,7,1970);
}
public void Change1 (int i) {
i = 1234;
}
For this code, date is a local variable, i,d,m,y is a local variable, and Day,month,year is a member variable.
The following analysis of the code execution time changes:
1. The main method begins execution: int date = 9; Date local variables, underlying types, references, and values are present in the stack.
2. Test test = new test (); Test is an object reference, exists in the stack, and the object (new Test ()) exists in the heap.
3. Test.change (date); I is a local variable, and the reference and value exist in the stack. When the method change execution is complete, I will disappear from the stack.
4. BirthDate d1= new BirthDate (7,7,1970); D1 is an object reference, exists in the stack, the object (new BirthDate ()) exists in the heap, where D,m,y is stored in the stack for local variables, and their type is the underlying type, so their data is also stored in the stack. Day,month,year are member variables that are stored in the heap (new BirthDate ()). When the birthdate construction method finishes executing, the d,m,y disappears from the stack.
After the 5.main method executes, the date variable, TEST,D1 reference will disappear from the stack, new test (), new BirthDate () will wait for garbage collection.
Java heap, stack, and constant pool details (II.)
1. Stacks and heaps (heap) are places that Java uses to store data in RAM. Unlike C + +, Java automatically manages stacks and heaps, and programmers cannot directly set up stacks or heaps.
2. The advantage of the stack is that the access speed is faster than the heap, second only to the registers directly in the CPU. However, the disadvantage is that the size and lifetime of the data in the stack must be deterministic and inflexible. In addition, the stack data can be shared, see 3rd.
The advantage of the heap is that the memory size can be allocated dynamically, and the lifetime does not have to tell the compiler beforehand that the Java garbage collector automatically collects the data that is no longer in use. However, the disadvantage is that the access speed is slower due to the dynamic allocation of memory at run time.
3. There are two kinds of data types in Java.
One is the basic type (primitive types), a total of 8 kinds, namely int, short, long, byte, float, double, Boolean, char (note, and no basic type of string). The definition of this type is through such as int a = 3; Long B = 255L; the form to be defined, called an automatic variable. It is worth noting that the automatic variable is a literal value, not an instance of a class, that is not a reference to a class, there is no class here. such as int a = 3; Here A is a reference to the int type, pointing to the literal value of 3. The data of these literals, due to the size of the known, the lifetime of the known (these values are fixed in a program block, the program block exits, the field value disappears), for the sake of speed, it exists in the stack. In addition, the stack has a very important particularity, is that there is data in the stack can be shared. Suppose we define int a = 3 at the same time; int b = 3; the compiler processes int a = 3 First, it creates a reference to a variable in the stack, and then looks for an address with a literal value of 3, and then finds an address that holds the literal value of 3, and then points A to the address of 3. then the int b = 3 is processed, and after the reference variable of B is created, B is pointed directly to the address of 3 because there are already 3 literals in the stack. In this case, A and B both point to 3. It is particularly important to note that the reference to this literal is different from the reference to the class object. Assuming that a reference to two class objects points to an object at the same time, if an object reference variable modifies the internal state of the object, then another object reference variable will immediately reflect that change. Conversely, modifying its value by a reference to a literal value does not result in another case where a reference to that literal is changed. As in the example above, we define the value of a and B and then make a=4; then B will not be equal to 4 or equal to 3. Inside the compiler, when it encounters A=4, it will re-search the stack for a literal value of 4, and if not, re-open the value of the address 4, and if so, point a directly at the address. Therefore the change of a value does not affect the value of B.
The other is the wrapper class data, such as Integer, String, double, and so on, the corresponding basic data types are wrapped up class. These classes of data all exist in the heap, and Java uses the new () statement to tell the compiler that it is dynamically created as needed at run time, so it is more flexible, but the disadvantage is that it takes more time.
Here are some examples: Java code
public class Test {
public static void Main (string[] args)
{
int a1=1;
int b1=1;
int c1=2;
int d1=a1+b1;
Integer a = 1;
Integer B = 2;
Integer C = 3;
Integer d = 3;
Integer e = 321;
Integer f = 321;
Long g = 3L;
System.out.println (A1==B1); True result 1
System.out.println (C1==D1); True result 2
System.out.println (C==d); True result 3
System.out.println (E==F); False result 4
}
}
Analysis:
The result 1:a1==b1 as described above, will open up storage space in the stack to store data.
Result 2: First it will create a reference in the stack with a variable of C1, and then find an address with a literal value of 2, not found, open a 2 of the value of the address, and then the C1 point to 2 address, D1 for two literal added also 2, because in the stack has 2 this literal value, The D1 points directly to the address of 2. In this way, the C1 and D1 both point to 3. Before analyzing the results below let's take a look at the Java Auto-unpacking and boxing: when auto-boxing, when int becomes integer, there are rules, when the value of your int is -128-integercache.high (127), Instead of returning an integer object that is new, it is an integer object that has been cached in the heap (we can understand that the system has cached an integer from 128 to 127 into an integer array, If you want to turn an int into an integer object, first go to the cache, find the words to return the reference directly to you, no need to new one, if not -128-integercache.high (127) Returns an integer object that is new.
Result 3: Since 3 is within range so the data is taken from the cache, and C and D point to the same object, the result is true;
Result 4: Because 321 is not in the range so the data is not taken from the cache but there is a new object alone, E and F do not point to the same object, the result is false;
4. String is a special wrapper class data. That is, it can be created in the form of string str = new String ("abc"), or in the form of string str = "abc" (In contrast, before JDK 5.0, you have never seen an expression of integer i = 3; because class and literal literals are not can be generic except for string. In JDK 5.0, this expression is possible! Because the compiler is converting the integer i = new Integer (3) in the background. The former is the process of creating a canonical class, that is, in Java, everything is an object, and the object is an instance of the class, all created in the form of new (). Some classes in Java, such as the DateFormat class, can return a newly created class through the class's getinstance () method, which seems to violate this principle. actually otherwise The class uses a singleton pattern to return an instance of the class, except that the instance is created inside the class through new (), and getinstance () hides this detail from the outside. So why is the case in string str = "abc", not created by new (), a violation of the above principle? Not really.
4 (1) string str = "ABC" Procedure for creating an object 1 First look in the constant pool for the existence of the content as "ABC" string object 2 if it does not exist, create "ABC" in the Constant pool and let Str refer to the object 3 if it exists, let Str refer to the object directly
As to how "ABC" is saved, where is it stored? The constant pool is part of the class information, and the class information is reflected in the JVM memory model that corresponds to the method area that exists in the JVM memory model, meaning that the constant pool concept in this class information exists in the method area, and the method area is allocated by the JVM in the heap in the JVM memory model, so "ABC" Can be said to exist in the heap (and some data, in order to distinguish the heap of the method area from the JVM heap, the method area is called the stack). In this case, "ABC" is written to the bytecode at compile time, so when class is loaded, the JVM allocates memory for "ABC" in the constant pool, so it is similar to the static zone.
4 (2) string str = new String ("abc") creates an instance of the procedure 1 first in the heap (not the constant pool) to create a specified object "ABC" and to have the STR reference point to the object 2 is viewed in the string constant pool, if there is a content of "ABC" string object 3 if present , the new string object is associated with the object in the string constant pool 4 if it does not exist, a string object with the content "ABC" is created in the string constant pool, and the object in the heap is associated with the Intern method can return a reference to the object of the string in the constant pool. You can test the Java code simply by following the code
Class Stringtest {
public static void Main (string[] args) {
String str1 = "abc";
String str2 = new String ("abc"). Intern ();
System.out.println (STR1==STR2);
}
}
An initially empty string pool, which is privately maintained by the class string. When the Intern method is called, if the pool already contains a string equal to this string object (as determined by the Equals (Object) method), the string in the pool is returned. Otherwise, this string object is added to the pool and a reference to this string object is returned. It follows the following rules: For any two strings s and T, s.intern () = = T.intern () is true if and only if S.equals (t) is true. So string str1 = "abc", STR1 refers to the object of the constant pool (method area), and string str2 = new String ("abc"), str2 refers to the object in the heap, so the memory address is different, but the content is the same, so = = is false, and Equals is True
4 (3) String str1 = "abc"; String str2 = "AB" + "C"; STR1==STR2 is ture because string str2 = "AB" + "C" will look in the constant pool when there is content as "ABC" string object, if there is a direct let str2 refer to the object, obviously string str1 = "ABC" when it says, An "ABC" object is created in the constant pool, so str1 references the object, STR2 also references the object, so STR1==STR2
4 (4) String str1 = "abc"; String str2 = "AB"; String STR3 = str2 + "C"; STR1==STR3 is false because string str3 = str2 + "C" involves the addition of variables (not all constants), so a new object is generated, and its internal implementation is the first new one StringBuilder, then append (str2), Append ("C"); then let str3 refer to the object returned by ToString () If you want to know more details, you can view the anti-compilation code yourself, and see that the anti-compilation code can be used with JAVAP.
That is, javap-c-verbose the class file (. Class) to view
Example of the above code
Javac Stringtest.java//compiling
Javap-c-verbose stringtest//Decompile
4 (5) String str1 = "abc";
String str2 = "abc";
System.out.println (STR1==STR2); True Note that
We do not use Str1.equals (STR2) in this way, as this will compare the values of two strings for equality. = = number, as described in the JDK, returns true only if two references point to the same object. And what we're looking at here is whether str1 and str2 all point to the same object. The result shows that the JVM created two references str1 and str2, but only one object was created, and two references pointed to the object.
4 (6) String str1 = "abc";
String str2 = "abc";
str1 = "BCD";
System.out.println (str1 + "," + str2); BCD, ABC
System.out.println (STR1==STR2); False This means that changes in the assignment result in a change in the class object reference, and str1 points to another new object! And str2 still points to the original object. In the example above, when we change the value of str1 to "BCD", the JVM discovers that there is no address for that value in the constant pool, opens up this address and creates a new object whose string value points to the address. In fact, the string class is designed to be immutable (immutable) classes. If you want to change its value, yes, but the JVM silently creates a new object at run time based on the new value, and then returns the address of the object to the reference of the original class. This creation process is entirely automatic, but it takes up more time. In the environment that is more sensitive to time requirements, it will have some adverse effects.
4 (7)
String str1 = "abc";
String str2 = "abc";
str1 = "BCD";
String STR3 = str1;
System.out.println (STR3); Bcd
String STR4 = "BCD";
System.out.println (str1 = = STR4); True STR3 the object's reference points directly to the object pointed to by STR1 (note that STR3 does not create a new object). When str1 changes its value, it creates a reference str4 of string and points to the new object created by str1 modifying the value. It can be found that this time STR4 also did not create a new object, thereby re-sharing the data in the stack.
4 (8)
Let's look at the following code again.
String str1 = new String ("abc");
String str2 = "abc";
System.out.println (STR1==STR2); False creates two references. Two objects were created. Two references point to a different two objects, respectively. String str1 = "abc"; String str2 = new String ("abc"); System.out.println (STR1==STR2); False creates two references. Two objects were created. Two references point to a different two objects, respectively. The above two code shows that as long as new () is used to create the object, it is created in the heap, and its string is stored separately, even if the data in the stack is the same, it is not shared with the data in the stack.
5. The value of the data type wrapper class cannot be modified. Not only the value of the string class cannot be modified, but all data type wrapper classes cannot change their internal values.
6. CONCLUSIONS AND recommendations:
(1) When we use a format definition class such as String str = "ABC", we always want to think of course that we created the object str of the String class. Worry about traps! The object may not have been created! The only certainty is that a reference to the string class was created. As to whether the reference is pointing to a new object, it must be considered in terms of context, unless you create a new object with a prominent way through the new () method. Therefore, it is more accurate to say that we have created a reference variable to the object of the String class str, which refers to a variable that points to a string class with the value "ABC". Being aware of this is helpful in troubleshooting bugs that are difficult to find in a program.
(2) The use of string str = "abc", in a way that can improve the speed of the program to a certain extent, because the JVM will automatically based on the actual data in the stack to determine whether it is necessary to create a new object. In the case of string str = new String ("abc"), the code creates a new object in the heap, regardless of whether the string value is equal or not, and it is necessary to create a new object, thereby aggravating the burden of the program. This idea should be the idea of the meta-mode, but it is not known whether the internal JDK implements this pattern.
(3) Use the Equals () method when comparing the values in the wrapper class, and use the = = when testing whether the references to the two wrapper classes point to the same object.
(4) Because of the immutable nature of the string class, you should consider using the StringBuffer class when a string variable needs to change its value frequently to improve program efficiency
That is All~~~thanks!!!
Detailed explanation of Java heap, stack and Chang, and related string (GO)