Deep Java core Java memory allocation principle explaining
Introduction: Stack, heap, Chang, although the same is the Java memory allocation operation area, but its scope of application and function is very different. This article will delve into the Java core and explain in detail the knowledge of Java memory allocation.
Java memory allocation and management is one of the core technologies of Java, before we introduced the Java memory management and memory leaks and Java garbage collection knowledge, today we go deep into the Java core, the detailed introduction of Java in memory allocation knowledge. In general, Java involves the following areas in memory allocation:
Register: We can't control it in the program
Stack: A reference to a primitive type of data and objects, but the object itself is not stored in the stack, but is stored in the heap
Heap: Storing data generated with new
Static domain: Static members that are stored in the object with static definitions
Constant pool: Storing constants
Non-RAM storage: Persistent storage space such as hard drives
Stacks in Java memory allocation
Some basic types of variable data and object reference variables that are defined in the function are allocated in the function's stack memory. When a variable is defined in a block of code, Java allocates memory space for the variable in the stack, and when the variable exits the scope, Java automatically frees the memory space allocated for the variable, and the memory space is immediately available for another use.
Heap in Java memory allocation
Heap memory is used to hold objects and arrays created by new. The memory allocated in the heap is managed by the automatic garbage collector of the Java Virtual machine.
After generating an array or an object in the heap, you can also define a special variable in the stack that is equal to the first address of the array or object in the heap memory, and this variable in the stack becomes the reference variable of the array or object. A reference variable is a name that is an array or an object, and you can use reference variables from the stack to access the arrays or objects in the heap later in your program. A reference variable is equivalent to a name that is an array or an object.
A reference variable is a normal variable that is allocated in the stack when defined, and the reference variable is freed after the program runs outside its scope. While the array and the object itself are allocated in the heap, the memory occupied by the array and the object itself is not freed, even if the program runs beyond the block of code that uses new to produce the array or object's statement, and the array and object are pointing to it without a reference variable.
Time, only to become garbage, cannot be used, but still occupy memory space, at a subsequent uncertain time by the garbage collector to take Away (released). This is why the Java comparison accounts for memory.
In fact, the variables in the stack point to the variables in the heap memory, which is the pointer in Java! Chang (Constant Pool)
Chang refers to some data that is determined at compile time and is saved in the compiled. class file. In addition to the constant values (final) that contain the various basic types defined in the code (such as int, long, and so on) and object types (such as strings and arrays), there are also some symbolic references that appear as text, such as:
The fully qualified name of the class and interface;
The name and descriptor of the field;
Methods and names and descriptors.
The virtual machine must maintain a constant pool for each mounted type. A constant pool is an ordered set of constants used by that type, including direct constants (String,integer and floating point constants), and symbolic references to other types, fields, and methods.
For a string constant, its value is in a constant pool. The Chang in the JVM exists as a table in memory, and for string types there is a fixed-length constant_string_info table for storing literal string values, note that the table stores only literal string values and does not store symbol references. In this case, there should be a clearer understanding of where the string values in the constant pool should be stored. When the program executes, the constant pool is stored in the method area, not the heap.
Heap and Stack
The Java heap is a run-time data area in which objects allocate space. These objects are established through directives such as new, NewArray, Anewarray, and Multianewarray, and they do not require program code to be explicitly released. Heap is responsible for garbage collection, the advantage of the heap is the ability to dynamically allocate memory size, the lifetime does not have to tell the compiler beforehand, because it is at runtime to allocate memory dynamically, Java garbage collector will automatically take away these no longer use data. However, the disadvantage is that the access speed is slower due to the dynamic allocation of memory at run time.
The advantage of the stack is that the access speed is faster than the heap, after the register, the stack data can be shared. However, the disadvantage is that the size and lifetime of the data in the stack must be deterministic and inflexible. The stack mainly contains some basic types of variable data (int, short, long, byte, float, double, Boolean, char) and object handle (reference).
Stack has a very important particularity, is that there is data in the stack can be shared. Let's say we define both:
1. Int a = 3;
2. Int B = 3;
The compiler processes int a = 3 First, it creates a reference to a variable in the stack, and then finds out if there is a value of 3 in the stack, and if it does not, it stores the 3 in and then points a to 3. the int b = 3 is then processed;
After the reference variable for B, because there are already 3 values in the stack, B points directly to 3. In this case, A and B both point to 3.
At this point, if you make a=4 again, then the compiler will re-search the stack for 4 values, if not, then store 4 in, and a point to 4; Therefore the change of a value does not affect the value of B.
It is important to note that this sharing of data with two object references also points to an object where this share is different, because the modification of a does not affect B, which is done by the compiler, which facilitates space saving. An object reference variable modifies the internal state of the object, affecting another object reference variable.
String is a special wrapper class data. Can be used:
1. String str = new String ("abc");
2. String str = "ABC";
Two forms, the first is to create new objects with new (), which is stored in the heap. A new object is created each time the call is made. The second is to create an object reference to the string class in the stack str, and then through the symbol reference to the string constant pool to find there is no "ABC", if not, the "ABC" into the string constant pool, and the Str point to "ABC", if there is already "ABC" The STR directly points to "ABC".
Use the Equals () method when comparing values within a class, and when testing two wrapper classes for reference to the same object, use = =, the following example illustrates the above theory.
1. String str1 = "abc";
2. String str2 = "abc";
3. SYSTEM.OUT.PRINTLN (STR1==STR2); True
You can see that str1 and str2 are pointing to the same object.
1. String str1 =new string ("abc");
2. String str2 =new string ("abc");
3. SYSTEM.OUT.PRINTLN (STR1==STR2); False
The new method is to generate different objects. Each time one is generated.
So the second way to create multiple "abc" strings, in memory in fact there is only one object. This writing is advantageous and saves memory space. At the same time it can improve the speed of the program to some extent, because the JVM will automatically determine whether it is necessary to create new objects based on the actual data in the stack. 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.
On the other hand, it is important to note that when you define a class using a format such as String str = "ABC", you always want to assume, of course, that the object that created the string class is Str. Worry about traps! The object may not have been created! Instead, it might just point to an object that was previously created. Only through the new () method can you guarantee that a new object is created each time.
Because of the immutable nature of the string class, you should consider using the StringBuffer class to improve program efficiency when a string variable needs to change its value frequently. 1. The string is not the first of 8 basic data types, string is an object. Because the default value of the object is NULL, the default value of string is also null, but it is a special object that has some features that other objects do not have.
2. New string () and new String ("") are all declarations of a new empty string, that is, the empty string is not null;
3. String str= "Kvill"; string Str=new string ("Kvill") difference
Example:
1. String s0= "Kvill";
2. String s1= "Kvill";
3. String s2= "kv" + "ill";
4. SYSTEM.OUT.PRINTLN (S0==S1);
5. SYSTEM.OUT.PRINTLN (S0==S2);
The result is: true True
First, we need to know the result. Java ensures that a string constant has only one copy.
Because the "Kvill" in S0 and S1 in the example are string constants, they are determined at compile time, so s0==s1 is true, and "kv" and "ill" are also string constants, and when a string is concatenated by multiple string constants, it is itself a string constant. So S2 is also parsed as a string constant at compile time, so S2 is also a reference to "Kvill" in the constant pool. So we come to s0==s1==s2; The string created with the new string () is not a constant and cannot be determined at compile time, so the string created by new string () is not placed in a constant pool and has its own address space.
Example:
1. String s0= "Kvill";
2. String S1=new string ("Kvill");
3. String s2= "kv" + new string ("ill");
4. SYSTEM.OUT.PRINTLN (S0==S1);
5. SYSTEM.OUT.PRINTLN (S0==S2);
6. SYSTEM.OUT.PRINTLN (S1==S2);
The result is: false
False false
In Example 2, S0 or "Kvill" in a constant pool, s1 because it cannot be determined at compile time, is a reference to the new object "Kvill" that was created at run time, S2 because there is a second part new String ("ill") so it cannot be determined at compile time, so it is also a newly created object " Kvill "The application of the", and understand that this will know why the result is obtained.
4. String.intern ():
One more point: the constant pool that exists in the. class file is loaded by the JVM at run time and can be expanded. The Intern () method of string is a method of extending a constant pool, and when a string instance str calls the Intern () method, Java looks for the same Unicode string constant in the constant pool, if any, returns its reference, if not, in the usual Add a string of Unicode equal to STR in the volume pool and return its reference; see the example.
Example:
1. String s0= "Kvill";
2. String S1=new string ("Kvill");
3. String S2=new string ("Kvill");
4. SYSTEM.OUT.PRINTLN (S0==S1);
5. System.out.println ("**********");
6. S1.intern ();
7. S2=s2.intern (); Assign a reference to "Kvill" in the constant pool to S2
8. SYSTEM.OUT.PRINTLN (S0==S1);
9. System.out.println (S0==s1.intern ());
System.out.println (S0==S2);
The result is: false false//although S1.intern () is executed, but its return value is not assigned to S1 TRUE//Description S1.intern () returns the reference true of "Kvill" in the constant pool
Finally I break a wrong understanding: Some people say, "using the String.intern () method, you can save a string class to a global string table, if a Unicode string with the same value is already in the table, Then the method returns the address of the existing string in the table, and if there are no strings of the same value in the table, register your own address in the table "If I interpret this global string table as Chang, his last word," if there are no strings of the same value in the table, register your own address in the table "Is wrong:
Example:
1. String S1=new string ("Kvill");
2. String S2=s1.intern ();
3. System.out.println (S1==s1.intern ());
4. System.out.println (s1+ "" +s2);
5. System.out.println (S2==s1.intern ());
Result: false Kvill Kvill True
In this class we do not have the reputation of a "kvill" constant, so the constant pool in the beginning there is no "Kvill", when we call S1.intern () in the constant pool after the new "Kvill" constant, the original is not in the constant pool "Kvill" still exists, is not " Register your own address in the constant pool.
S1==s1.intern () is false to indicate that the original "Kvill" still exists; S2 is now the address of "Kvill" in the constant pool, so there is S2==s1.intern () true.
5. About Equals () and = =:
This is simple for string to compare whether the Unicode sequence of the two strings is equivalent, if equal returns true, and = = is the same as the address of the two strings, that is, a reference to the same string.
6. About the string is immutable
This said again a lot, as long as we know that the string instance once generated will not be changed, such as: string Str= "kv" + "ill" + "+" ans "; There are 4 string constants, first "KV" and "ill" generate "Kvill" in memory, and then "Kvill" and "Generate" Kvill "in memory, and finally generated" Kvill ans ", and the address of the string to the STR, This is because the "immutable" of string produces a lot of temporary variables, which is why it is recommended to use StringBuffer, because StringBuffer can be changed.
Here are some string-related FAQs:
Final usage and understanding in string final StringBuffer a = new StringBuffer ("111"); Final StringBuffer B = new StringBuffer ("222"); a=b;//This sentence compilation does not pass final stringbuffer a = new StringBuffer ("111"); A.append ("222");//Compile Through
As you can see, final is valid only for the reference "value" (that is, the memory address), which forces the reference to point only to the object that was initially pointed to, and changes its point to cause a compile-time error. Final is not responsible for the change in the object it points to.
Several examples of string constant pool problems
Here are a few common examples of comparative analysis and understanding:
1. String a = "A1";
2. String B = "a" + 1;
3. System.out.println ((A = = b)); result = True
4. String a = "atrue";
5. String B = "a" + "true";
6. System.out.println ((A = = b)); result = True
7. String a = "a3.4";
8. String B = "a" + 3.4;
9. System.out.println ((A = = b)); result = True
Analysis: JVM for string constant "+" number connection, the program compile period, the JVM will be the constant string "+" connection optimization to the concatenated value, take "a" + 1, the compiler is optimized in class is already A1. The value of its string constants is determined at compile time, so the final result of the above program is true.
1. String a = "AB";
2. String BB = "B";
3. String B = "a" + BB;
4. System.out.println ((A = = b)); result = False
Analysis: JVM for string reference, because in the string "+" connection, there is a string reference exists, and the reference value in the program compilation period is not determined, that is, "a" + BB can not be optimized by the compiler, only during the program run time to dynamically allocate and the new address after the connection to B. So the result of the above program is also false.
1. String a = "AB";
2. Final String BB = "B";
3. String B = "a" + BB;
4. System.out.println ((A = = b)); result = True
Analysis: The only difference between [3] is that the BB string has a final decoration, and for a final modified variable, it is parsed at compile time to a local copy of the constant value stored in its own constant pool or embedded in its byte stream. So at this point the "a" + BB and "a" + "B" effect is the same. Therefore, the result of the above program is true.
1. String a = "AB";
2. Final String BB = GETBB ();
3. String B = "a" + BB;
4. System.out.println ((A = = b)); result = False
5. Private static String GETBB () {
6. Return "B";
7.}
Analysis: The JVM for the string reference BB, its value in the compilation period can not be determined, only after the program run time call method, the return value of the method and "a" to dynamically connect and assign the address to B, so the result of the above program is false.
From the above 4 examples can be obtained:
String s = "a" + "B" + "C"; is equivalent to string s = "abc"; String a = "a"; String B = "B"; String c = "C"; String s = a + B + C;
This is not the same, the end result equals:
1. StringBuffer temp = new StringBuffer ();
2. Temp.append (a). Append (b). append (c);
3. String s = temp.tostring ();
From the above analysis results, it is not difficult to infer that the string using the Join operator (+) inefficiency reason analysis, such as the code:
1. public class Test {
2. public static void Main (String args[]) {
3. String s = null;
4. for (int i = 0; i <; i++) {
5. S + = "a";
6.}
7.}
8.}
Every time you do it, you produce a StringBuilder object and then throw it away after append. The next time the loop arrives, it re-generates the StringBuilder object and then append the string so that it loops until the end. If we use the StringBuilder object directly for Append, we can save N-1 time to create and destroy objects. So for applications that want to concatenate strings in a loop, the StringBuffer or Stringbulider objects are generally used for append operations.
The Intern method of the string object is understood and analyzed:
1. public class Test4 {
2. private static String a = "AB";
3. public static void Main (string[] args) {
4. String S1 = "a";
5. String s2 = "B";
6. String s = s1 + s2;
7. SYSTEM.OUT.PRINTLN (s = = a);//false
8. System.out.println (S.intern () = = a);//true
9.}
10.}
The problem with Java is that it is a constant pool. For the s1+s2 operation, a new object is recreated in the heap, and s holds the contents of the new object in the heap space, so s is not equal to the value of a. When you call the S.intern () method, you can return the address value of s in the constant pool, because the value of a is stored in a constant pool, so the values of s.intern and a are equal.
Summarize
A reference to the local variable data and objects (String, Array, object, and so on) that are used to hold some raw data types in the stack. But not the object content
The heap contains objects created using the New keyword.
A string is a special wrapper class whose reference is stored in the stack, and the object content must be set differently (Chang and heap) depending on how it was created. Some compile time has been created, stored in a string constant pool, and some runtime is created. Use the new keyword to store in the heap.
Detailed introduction to Java memory management and memory leaks
Introduction: Java memory leaks are the problems that every Java programmer will encounter, the program is running all the normal local, but the deployment to the far end of the memory unlimited growth, and finally the system is paralyzed, then how the fastest best detection program stability, to prevent system crashes, The author uses his own personal experience to share with the netizens how to solve these problems.
Java is now very popular as one of the most popular programming languages on the Internet. Our web applications are primarily developed in the Java language and are broadly divided into three levels of clients, servers, and databases. During the testing process, we found that a program module system memory and CPU resource consumption increased sharply, and continued to grow until java.lang.OutOfMemoryError occurred. The analysis of Java memory leaks is a major factor in destroying the system. Here we share with you the process of detecting and processing Java memory leaks that we have encountered during the development process.
This article first describes the memory management of Java and the causes of Java memory leaks.
I. How Java manages memory
To determine if there is a memory leak in Java, we must first understand how Java manages memory. The memory management of Java is the allocation and release of objects. In Java, the allocation of memory is done by the program, and the release of memory is done by the garbage collector (garbage COLLECTION,GC), the programmer does not need to call the function to free memory, but it can only reclaim the useless and no longer referenced by other objects of the space occupied by those objects.
The memory garbage collection mechanism of Java is to check the reference chain from the main running object of the program, and when it is traversed, it is found that there are no referenced orphaned objects as garbage collection. In order to properly dispose of objects, the GC must monitor the running state of each object, including the application, reference, reference, assignment, etc. of the object, which the GC needs to monitor. The object's state is monitored to release the object more accurately and in a timely manner, and the fundamental principle of releasing the object is that the object is no longer referenced.
In Java, these useless objects are collected by the GC, so programmers do not need to consider this part of the memory leak. Although we have several functions that can access the GC, such as the function System.GC () that runs the GC, the function does not guarantee that the JVM's garbage collector will execute, as defined by the Java language Specification. Because different JVM implementations may use different algorithms to manage the GC. Typically, GC threads have a lower priority level. There are a number of policies that the JVM calls the GC, some of which are used to a certain extent, the GC starts to work, there are timed executions, there is a gentle execution of the GC, and some interrupt-execution GC. But generally speaking, we don't need to care about this.
Two. What is a memory leak in Java
The main reason for a memory leak is that you previously requested a memory space and forgot to release it. If a reference to a useless object exists in the program, those objects will reside in memory and consume memory because the garbage collector GC cannot be verified that the objects are no longer needed. If there is a reference to the object, the object is defined as a "valid activity" and is not freed. To make sure that the object's memory will be recycled, we must make sure that the object is no longer in use. The typical practice is to set the object data member to null or to remove the object from the collection. However, when a local variable is not required, it is not required to be significantly null, because when a method executes, these references are automatically cleaned up.
In Java, the memory leak is the existence of some assigned objects, these objects have the following two characteristics, first of all, these objects are referenced, that is, in the direction of the tree, there is a branch path can be connected with, and secondly, these objects are not
The program will no longer use these objects. If the object satisfies both conditions, these objects can be judged as a memory leak in Java, which is not reclaimed by the GC, but it consumes memory.
Here is a frequently seen example, in the following code, the loop applies to the Object object, and put the requested objects into a vector, if only the object itself, but because the vector still refers to the object, so this object is not recyclable GC. Therefore, if the object has to be removed from the vector after it has been added to the vector, the simplest way is to set the vector object to null.
1. Vector v = new vector (10);
2. for (int i = 1; i <; i++)
3. {
4. Object o = new Object ();
5. V.add (o);
6. O = null;
7.}//at this point, all object objects are not freed because the variable v refers to these objects.
In fact, these objects are already useless, but also referenced, the GC is powerless (in fact, the GC thinks it is useful), which is the most important cause of memory leaks. Then cite another example to illustrate the memory leaks in Java. Suppose there is a log class logger, which provides a static log (String msg), and any other class can call LOGGER.LOG (message) to record the contents of the message into the system's log file.
The logger class has a static variable of type HashMap temp, and each time the log (message) is executed, the value of the message is first written to temp (with the current thread + current time as the key). Delete the entries in temp from the current thread and the current time key before exiting. Note that the current time here is constantly changing, so log execution deletes entries before exiting, and cannot delete entries that were written at the beginning of the execution. Thus, any string passed as a parameter to log will eventually be referenced by the logger static variable temp and cannot be recycled, and this object remains what we call a Java memory leak. In general, memory leaks in memory management are the main reason: object references that remain but are never used again.
The JVM's garbage collection mechanism for detailed understanding and tuning
Introduction: GC is a garbage collection mechanism that is used by the JVM to release memory that is consumed by objects that are no longer in use. The Java language does not require the JVM to have a GC, nor does it stipulate how the GC works. However, the common JVM has GC, and most GC uses a similar algorithm to manage memory and perform collection operations.
GC Overview for 1.JVM
A GC is a garbage collection mechanism that is used by the JVM to free memory that is consumed by objects that are no longer in use. The Java language does not require the JVM to have a GC, nor does it stipulate how the GC works. However, the common JVM has GC, and most GC uses a similar algorithm to manage memory and perform collection operations.
After fully understanding the garbage collection algorithm and the execution process, it can effectively optimize its performance. Some garbage collection is dedicated to special applications. For example, real-time applications are primarily designed to avoid garbage collection outages, while most OLTP applications focus on overall efficiency. With an understanding of the workload of the application and the garbage collection algorithms supported by the JVM, the garbage collector can be optimally configured.
The purpose of garbage collection is to clear objects that are no longer in use. The GC determines whether to collect the object by determining whether the object is referenced by the active object. The GC first determines whether the object is ready to be collected. Two common methods are reference counts and object reference traversal.
1.1. Reference counting
The reference count stores all references to a particular object, that is, when the application creates a reference and the reference goes out of scope, the JVM must increase or decrease the number of references appropriately. When an object has a reference count of 0 o'clock, garbage collection is possible.
1.2. Object reference traversal
Earlier JVMs used reference counting, and most JVMs now traverse with object references. Object reference traversal starts with a set of objects and recursively determines the reachable (reachable) object along each link on the entire object graph. If an object cannot arrive from one (at least one) of these root objects, it is garbage collected. During the object traversal phase, the GC must remember which objects can be reached in order to delete the Unreachable object, which is known as the markup (marking) object.
Next, the GC wants to delete the unreachable object. When deleted, some GC simply scans the stack, removes unmarked unmarked objects, and frees their memory to generate new objects, called Purge (sweeping). The problem with this approach is that memory is broken into small chunks, which are not sufficient for new objects, but are very large in combination. As a result, many GCs can reorganize objects in memory and compress (compact) to make available space.
To do this, the GC needs to stop other active activities. This approach means that all application-related work is stopped and only the GC is running. As a result, many miscellaneous requests are added and subtracted during the response. In addition, more complex GCS are constantly increasing or running concurrently to reduce or eliminate the interruption of the application. Some GC uses a single thread to do the work, while others use multithreading to increase efficiency.
2. Several garbage collection mechanisms
2.1. Mark-Clear Collector
The collector first loops through the object graph and marks the reachable objects, then scans the stack for unmarked objects and frees up their memory. This collector typically uses a single thread to work and stops other operations.
2.2. Tag-Compression collector
Sometimes also called Mark-purge-compress collector, with the mark-purge collector has the same marking stage. In the second stage, the tag object is copied to the new domain of the stack to compress the stack. This collector also stops other operations.
2.3. Copy Collector
This collector divides the stack into two domains, often referred to as half-space. Using only half of the space at a time, the new object generated by the JVM is placed in the other half of the space. When the GC runs, it compresses the stack by copying the reachable object to the other half of the space. This method is suitable for short-lived objects, and continuous replication of long-lived objects results in reduced efficiency.
2.4. Incremental collector
The incremental collector divides the stack into multiple domains, collecting garbage from only one domain at a time. This can result in a smaller application outage.
2.5. Generational Collectors
This collector divides the stack into two or more domains for storing objects of different lifetimes. A new object generated by the JVM is typically placed in one of the domains. Over time, objects that continue to exist will receive a lifetime and go into a longer-lived domain. The generational collector uses different algorithms for different domains to optimize performance.
2.6. Concurrent Collector
The concurrent collector runs concurrently with the application. These collectors generally have to stop other operations to complete a particular task at some point (such as compression), but because other applications can perform other background operations, the actual time to interrupt other processing is greatly reduced.
2.7. Parallel collector
The parallel collector uses some traditional algorithms and uses multithreading to perform their work in parallel. The use of multithreading on multi-CPU machines can significantly improve the scalability of Java applications.
3.Sun HotSpot 1.4.1 JVM Heap Size adjustment
Sun HotSpot 1.4.1 uses a generational collector, which divides the heap into three main domains: new, old, and permanent. All new objects generated by the JVM are placed in the new domain. Once an object undergoes a certain number of garbage collection loops, it gets the usage period and goes into the old domain. In a permanent domain, the JVM stores the class and method objects. In terms of configuration, a permanent domain is a separate domain and is not considered part of the heap.
The following describes how to control the size of these fields. You can use-XMS and-xmx to control the entire heap's original size or maximum value.
The following command sets the initial size to 128M:
java–xms128m
–xmx256m to control the size of the new domain, you can use-xx:newratio to set the percentage of the new domain in the heap.
The following command sets the entire heap to 128m, the new domain ratio is set to 3, that is, the new domain is proportional to the old domain 1:3, and the new domain is 1/4 or 32M of the heap:
Java–xms128m–xmx128m–xx:newratio =3 can use-xx:newsize and-xx:maxnewsize to set the initial and maximum values for the new domain.
The following command sets the initial and maximum values of the new domain to 64m:
java–xms256m–xmx256m–xmn64m
The default size of the permanent domain is 4m. When you run the program, the JVM adjusts the size of the permanent domain to suit your needs. Each time the adjustment is made, the JVM performs a full garbage collection of the heap.
Use the-XX:MAXPERSIZE flag to increase the size of the permanent domain. When the WebLogic server application loads more classes, it is often necessary to increase the maximum value of the persistent domain. When the JVM loads a class, objects in the permanent domain increase sharply, allowing the JVM to constantly adjust the permanent domain size. To avoid adjustments, use the-XX:PERSIZE flag to set the initial value.
The following sets the permanent domain initial value to 32m and the maximum value to 64m.
java-xms512m-xmx512m-xmn128m-xx:permsize=32m-xx:maxpermsize=64m
By default, hotspot uses the replication collector in the new domain. This field is generally divided into three parts. The first part is Eden, which is used to generate new objects. The other two are called rescue spaces, and when Eden is full, the collector stops the application, copies all reachable objects to the current from rescue space, and once the current from rescue space is filled, the collector copies the reachable objects to the current to rescue space. From and to rescue space swap roles. The active objects will continue to replicate in the rescue space until they have been used and transferred to the old domain. Use-xx:survivorratio to control the size of new domain sub-spaces.
As with Newration, Survivorration prescribes the ratio of a rescue area to Eden space. For example, the following command sets the new domain to 64m,eden of 32m, each of which occupies 16m:
Java-xms256m-xmx256m-xmn64m-xx:survivorration =2
As mentioned earlier, the hotspot uses the replication collector for the new domain by default, and uses the tag-purge-compress collector for the old domain. Using the replication collector in a new domain has a lot of meaning, because most of the objects that the application generates are short-lived. Ideally, all transition objects will be collected when they are moved out of Eden Space. If this is the case, and the objects that move out of the Eden space are long-lived, you can theoretically move them into the old domain immediately, avoiding repeated duplication in the rescue space. However, applications do not fit into this ideal state because they have a small percentage of objects that are long-lived. It is best to keep these long-lived objects in the new domain, because copying a small portion of the object is always cheaper than compressing the old domain. To control the replication of objects in the new domain, you can use-xx:targetsurvivorratio to control the proportion of the rescue space (the value is set to save the empty
Use ratio between the two. If the salvage space is 1M, the value 50 indicates available 500K). The value is a percentage, and the default value is 50. When the larger stack uses a lower sruvivorratio, the value should be increased to 80 to 90 to make better use of the rescue space. The upper limit can be controlled with-xx:maxtenuring threshold.
To place all replication occurrences and to extend the object from Eden to the old domain, you can put the maxtenuring Threshold is set to 0. After the setup is complete, the rescue space is not actually used, so the survivorratio should be set to the maximum value to maximize Eden space, set as follows:
Java "-xx:maxtenuringthreshold=0–xx:survivorratio=50000"
Use of the 4.BEA JRockit JVM
The Bea WebLogic 8.1 uses a new JVM for the Intel platform. A folder similar to jrockit81sp1_141_03 can be seen in the list of BEA installations. This is the directory where Bea new JVM resides. Unlike hotspot, which compiles Java bytecode into code, it is pre-compiled into classes. JRockit also provides more granular functionality to observe the operating state of the JVM, primarily a standalone GUI console (only available for use with JRockit jrockit81sp1_141_ The 03 console monitors some CPU and memory parameters) or the WebLogic Server console.
The Bea JRockit JVM supports 4 types of garbage collectors:
4.1.1. Generational replication Collector
It is similar to the default generational collector working policy. The JRockit object is assigned in the new domain, which is the nursery in the document. This collector is best suited for small heap operations on single-CPU machines.
4.1.2. Single-Space concurrent collector
The collector uses the full heap and works with the background thread. Although this collector can eliminate interrupts, collectors take a long time to find dead objects, and the collector often runs when the application is processed. If the processor is unable to cope with the garbage generated by the application, it interrupts the application and closes the collection.
Generational concurrency collector This collector uses the exclusive copy collector in the care domain, and the concurrent collector in the old domain. Because it is more frequent than a single-space collector interrupt, it requires less memory and the application is running more efficiently, noting that a small care domain can cause a large number of temporary objects to be extended to the old domain. This can cause the collector to become overloaded and even perform the collection in an exclusive way of working.
4.1.3. Parallel collector
The collector also stops the work of other processes, but uses multithreading to speed up the collection process. Although it is more prone to long interruptions than other collectors, it generally makes better use of memory and has higher program efficiency.
By default, JRockit uses a generational concurrency collector. To change the collector, the-XGC:<GC_NAME> can be used, and the corresponding four collectors are gencopy,singlecon,gencon and parallel, respectively. You can use-XMS and-xmx to set the initial size and maximum value of a heap. To set up a care domain, use the-xns:java–jrockit–xms512m–xmx512m
–xgc:gencon–xns128m "Although the JRockit supports the-VERBOSE:GC switch, the information it outputs differs depending on the collector. The JRockit also supports the output of memory, load, and CodeGen.
Note: If you use the JRockit JVM, you can also use WLS's own console (C:\bea\jrockit81sp1_141_03\bin) to monitor some data, such as Cpu,memery. To be able to construct the monitor, the-xmanagement parameter must be added to the startweblogic.cmd when the service is started.
5. How to obtain information from the JVM for tuning
The-VERBOSE.GC switch displays the operation contents of the GC. Open it to show when the busiest and most idle collection behavior occurred, the amount of memory before and after collection, the time it took to collect, and so on. Open the-xx:+ printgcdetails switch to learn more about the changes in the GC. Open the-XX: + printgctimestamps switch to see when these garbage collections occur, measured in seconds since the JVM started. Finally, more detailed information about the heap is learned through the-XX: + PRINTHEAPATGC switch. To understand the situation of the new domain, you can use the-xx:=printtenuringdistribution switch to understand the object rights for the usage period.
6.PDM System JVM Tuning
6.1. Server: Premise memory 1G single CPU
This can be adjusted by using the following parameters:-server Enable server mode (this is recommended for server machines if there are more CPUs)
-xms,-xmx are generally set to the same size. 800m
-XMN is to set newsize and Maxnewsize as the same. 320m
-xx:persize 64m
-xx:newsize 320m This value is set to a large adjustable Da object area, reducing the number of full GC
-xx:maxnewsize 320m
-xx:newrato newsize is not set. 4
-xx:survivorratio 4
-XX:USERPARNEWGC can be used to set up parallel collections
-xx:parallelgcthreads can be used to increase the degree of parallelism 4
-XXUSEPARALLELGC You can use the parallel purge collector after setting
-xx:useadaptivesizepolicy works better with the previous one, and it can automatically optimize the new domain size and save space ratios
6.2. Client: Tuning the client JVM by setting parameters in the Jnlp file
JNLP parameters: Initial-heap-size and Max-heap-size
This adds the above parameters when generating the JNLP file in the framework's requestmanager, but these values are required to vary depending on the client's hardware state (such as the client's memory size, etc.). It is recommended that the two parameter values be set to 60% of the available memory for the client (to be tested). In order to dynamically generate JNLP, the above two parameter values can vary with the client, reliably taking the client system information and embedding these into the first page index.jsp as the parameters of the connection request.
After setting the above parameters, the VISUALGC can be used to observe some parameter states of garbage collection, and then make corresponding adjustments to improve performance. The general standard is to reduce the number of FULLGC, preferably hardware support using parallel garbage collection (requires multi-CPU).
Deep Java core Java memory allocation principle explaining