In addition to Weibo, there is also WeChat
Please pay attention
WeChat public account
Shulou
2025-01-19 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >
Share
Shulou(Shulou.com)06/02 Report--
This article mainly introduces "what is the basic principle of JVM garbage collection". In daily operation, I believe many people have doubts about what the basic principle of JVM garbage collection is. The editor consulted all kinds of materials and sorted out simple and easy-to-use operation methods. I hope it will be helpful to answer the doubts about "what are the basic principles of JVM garbage collection?" Next, please follow the editor to study!
The basic principle of JVM GC and GC algorithm
The memory allocation and collection of Java are all done automatically by the JVM garbage collection process. Unlike the C language, Java developers do not need to write their own code for garbage collection. This is one of the many popular features of Java that can help programmers write Java programs better.
Key terms of Java
JavaAPI: a series of packaged libraries that help developers create Java applications.
Java Development Kit (JDK): a set of tools to help developers create Java applications. JDK contains tools to compile, run, package, distribute, and monitor Java applications.
Java Virtual Machine (JVM): JVM is an abstract computer structure. The Java program is written according to the characteristics of JVM. JVM is specific to the operating system and can translate Java instructions into instructions of the underlying system and execute them. JVM ensures the platform independence of Java.
Java Runtime Environment (JRE): JRE contains the JVM implementation and Java API.
Java HotSpot virtual machine
Each JVM implementation may take a different approach to implementing the garbage collection mechanism. Before the acquisition of SUN, Oracle used JRockit JVM and after the acquisition used HotSpot JVM. Oracle currently has two JVM implementations and the two JVM implementations will merge into one after a period of time.
HotSpot JVM is part of the standard core components of the current Oracle SE platform. In this garbage collection tutorial, we will learn about garbage collection principles based on HotSpot virtual machines.
Java heap memory
It is necessary to understand the role of the JVM memory model in the heap. At run time, an instance of Java is stored in the heap memory area. When an object is no longer referenced, the condition is removed from heap memory. During the garbage collection process, these objects are removed from the heap memory and the memory space is reclaimed. There are three main areas of heap memory:
New generation (Young Generation)
Eden space (Eden space, any instance enters the runtime memory area through Eden space)
S0 Survivor space (S0 Survivor space, long-lived instances will be moved from Eden space to S0 Survivor space)
S1 Survivor space (instances that exist longer will be moved from S0 Survivor space to S1 Survivor space)
Old Generation instance will be upgraded from S1 to Tenured (lifetime generation)
Permanent Generation contains meta-information about classes, methods, and other details
The permanent generation space has been removed from the Java SE8 feature.
Java garbage collection is an automated process that manages the runtime memory used by programs. Through this automated process, JVM relieves programmers of the overhead of allocating and releasing memory resources in the program.
Start Java garbage collection
As an automated process, programmers do not need to start the garbage collection process explicitly in the code. System.gc () and Runtime.gc () are used to request JVM to start garbage collection.
Although this request mechanism gives programmers a chance to start the GC process, JVM is responsible for starting it. JVM can reject this request, so there is no guarantee that these calls will perform garbage collection. The timing of startup is determined by JVM and depends on whether the Eden area is available in heap memory. JVM leaves this choice to the implementation of the Java specification, and different implementations use different algorithms.
There is no doubt that we know that the garbage collection process cannot be enforced. I just found a meaningful scenario for calling System.gc (). Learn about the extreme situation where it is appropriate to call System.gc () through this article.
Trigger time (When) GC type of various GC
When it comes to GC types, it's even more interesting, because there are no unified strict boundaries in the industry, and there are no strict GC types, each with a set of names for a professor on the left and a set of names for an author on the right. Why is this the case, because GC types are related to collectors, and different collectors have their own unique collection types. Therefore, the author quotes R University's introduction of GC types here, and the author thinks it is more appropriate and accurate. It is as follows:
Partial GC: patterns that do not collect the entire GC heap
Young GC (Minor GC): collect only the GC of young gen
Old GC: only the GC of old gen is collected. Only CMS's concurrent collection is in this mode.
Mixed GC: collect the GC of the entire young gen and part of the old gen. Only the G1 has this mode.
Full GC (Major GC): collects patterns for all parts of the heap, including young gen, old gen, perm gen (if any), and so on.
Trigger time
As you can see above, GC type classification is related to collectors, so of course, the timing of GC trigger is different for different collectors. The author aims at the default serial GC:
Young GC: triggered when the eden area in the young gen is fully allocated. Note that some surviving objects in young GC are promoted to old gen, so the old gen usage usually increases after young GC.
Full GC: when preparing to trigger a young GC, if you find that the average promotion size of the previous young GC is larger than the remaining space of the current old gen, it will not trigger the young GC but instead trigger the full GC (because in the GC of HotSpot VM, except the concurrent collection of CMS, other GC that can collect old gen will collect the entire GC heap at the same time, including young gen, so there is no need to trigger a separate young GC in advance) Or, if there is a perm gen, full GC; or System.gc () or heap dump with GC should be triggered once when perm gen allocates space but there is not enough space. Full GC is also triggered by default.
Detailed explanation of FULL GC trigger conditions
In addition to calling System.gc directly, there are four situations that trigger Full GC execution.
Insufficient space in the Paleozoic era
The shortage of the old generation space occurs only when the new generation object is transferred and created as a large object or a large array. When the space is still insufficient after the execution of Full GC, the following error is thrown:
Java.lang.OutOfMemoryError: Java heap space
In order to avoid Full GC caused by the above two conditions, we should try our best to allow objects to be recycled in the Minor GC phase, to allow objects to survive in the new generation for a longer period of time, and not to create too large objects and arrays.
2. Permanet Generation space is full
Permanet Generation stores some class information, etc. When there are many classes to be loaded, reflected classes and methods called in the system, Permanet Generation may be full and Full GC will be executed if it is not configured to use CMS GC. If it still fails to recycle after Full GC, JVM will throw the following error message:
Java.lang.OutOfMemoryError: PermGen space
In order to avoid the Full GC phenomenon caused by full Perm Gen, the method that can be adopted is to increase the Perm Gen space or switch to using CMS GC.
3. Promotion failed and concurrent mode failure appear in CMS GC
For programs that use CMS for old GC, pay special attention to whether there are promotion failed and concurrent mode failure conditions in the GC log, which may trigger Full GC.
When promotion failed is in Minor GC, the survivor space cannot be put down, and the object can only be put into the old generation, and the old generation can not put it either; concurrent mode failure is caused by the lack of space in the old generation when there are objects to be put into the old generation during the execution of CMS GC.
The response is to increase the survivor space, Paleozoic space, or reduce the ratio of triggering concurrent GC, but in the versions of JDK 5.0 + and 6.0 +, it is possible that CMS triggers the sweeping action long after the remark is completed due to the bug29 of JDK. This situation can be avoided by setting-XX: CMSMaxAbortablePrecleanTime=5 (unit is ms).
Statistics show that the average size of Minor GC promoted to the Old Age is larger than the remaining space of the Old Age.
This is a more complex trigger situation. In order to avoid the shortage of space in the old generation caused by the promotion of the new generation to the old generation, Hotspot made a judgment during the Minor GC. If the average size of the promotion of the Minor GC to the old generation is larger than the remaining space of the old generation, then the Full GC will be triggered directly.
For example, after the program triggers Minor GC for the first time, the object with 6MB is promoted to the old generation, then when the next Minor GC occurs, first check whether the remaining space of the old generation is greater than 6MB, and if less than 6MB, execute Full GC.
When the new generation adopts PS GC, the method is slightly different. PS GC will also be checked after Minor GC. For example, after the first Minor GC in the above example, PS GC will check whether the remaining space of the old generation is greater than 6MB. If less, it will trigger the recycling of the old generation.
In addition to the above four situations, for Sun JDK applications that use RMI for RPC or management, Full GC is performed once an hour by default. You can prevent RMI from calling System.gc by setting the interval between Full GC execution through-java-Dsun.rmi.dgc.client.gcInterval=3600000 at startup or by using-XX:+ DisableExplicitGC.
Summary
Minor GC, Full GC trigger condition
Minor GC trigger condition: when the Eden area is full, trigger Minor GC.
Full GC trigger condition:
(1) when calling System.gc, the system recommends that Full GC be executed, but not necessarily.
(2) lack of space in the old years.
(3) the method is insufficient to remove space.
(4) the average size of memory entering the old age after passing Minor GC is larger than the available memory of the old age.
(5) if the object size is larger than the To Space available memory when copying from Eden area and From Space area to To Space area, the object is transferred to the old age, and the available memory of the old age is less than the size of the object.
What is Stop the world?
The Stop-The-World mechanism in Java, referred to as STW, means that when the garbage collection algorithm is executed, all other threads of the Java application are suspended (except the garbage collection helper). In Java, a global pause, global pause, all Java code stops, native code can execute, but cannot interact with JVM; these phenomena are mostly caused by gc.
Stop the World (STW) in GC is everyone's worst enemy. But many people may not know, in addition to GC,JVM, there will be a pause.
There is a special thread in JVM-VM Threads, which is specially used to execute some special VM Operation, such as dispatching GC,thread dump, etc., these tasks require the entire Heap and the state of all threads to be static and consistent. So JVM introduces the concept of a safe point (Safe Point) to find a way to notify all threads to enter a static safe point when VM Operation is needed.
In addition to GC, other VM Operation triggers for security points include:
1. JIT related, such as Code deoptimization, Flushing code cache
2. Class redefinition (instrumentation generated by e.g. Javaagent,AOP code implantation)
3. Biased lock revocation cancels bias lock
4. Various debug operation (e.g. Thread dump or deadlock check)
Java garbage collection process
Garbage collection is the process of reclaiming unused memory space and making it available to future instances.
Eden area: when an instance is created, it is first stored in the Eden area of the younger generation of heap memory.
Note: if you can't understand these words, I suggest you read this introduction to garbage collection, which details the memory model, JVM architecture, and these terms.
Survivor regions (S0 and S1): as part of the younger generation GC (Minor GC) cycle, surviving objects (still referenced) are moved from the Eden area to S0 in the Survivor area. Similarly, the garbage collector scans S0 and moves the surviving instance to S1.
Note: shouldn't the survivors of Eden and S0 move to S1? why move to S0 first and then from S0 to S1? )
Dead instances (no longer referenced) are marked as garbage collection. Depending on the choice of garbage collector (there are four commonly used garbage collectors, which will be introduced in the next tutorial), either the marked instances are constantly removed from memory, or the collection process is done in a separate process.
Old age: Old or tenured generation is the second logical area in heap memory. When the garbage collector executes the Minor GC cycle, the surviving instances in the S1 Survivor area are promoted to the old age, while unreferenced objects are marked for collection.
Old GC (Major GC): compared to the Java garbage collection process, the old age is the last stage of the instance life cycle. Major GC scans the garbage collection process in the old days. If instances are no longer referenced, they will be marked as recycled, otherwise they will remain in the old days.
Memory fragmentation: once an instance is removed from heap memory, its location becomes empty and can be used for future instance allocation. This free space will fragment the entire memory area. For rapid allocation of instances, defragmentation is required. Based on the different choices of the garbage collector, the reclaimed areas of memory are either constantly cleaned up or done in a separate GC process.
The termination of instances in garbage collection
Before releasing an instance and reclaiming memory space, the Java garbage collector calls the instance's respective finalize () method, giving the instance a chance to release the resources it holds. Although it is guaranteed that finalize () will be called before the memory space is reclaimed, there is no specified order and time. The order between multiple instances is unpredictable and may even occur in parallel. The program should not pre-adjust the order between instances and use the finalize () method to recycle resources.
Any exceptions that are not caught during the finalize process are automatically ignored, and then the instance's finalize process is canceled.
The garbage collection mechanism for weak references is not discussed in the JVM specification, and there are no clear requirements. The specific implementation is decided by the implementer.
Garbage collection is done by a daemon thread.
When does the object meet the criteria for garbage collection?
None of the instances are accessed by active threads.
A circular reference instance that is not accessed by any other instance.
There are different reference types in Java. Determining whether an instance meets the criteria for garbage collection depends on its reference type.
Reference type garbage collection strong reference (Strong Reference) does not conform to garbage collection soft reference (Soft Reference) garbage collection may be performed, but as a last resort weak reference (Weak Reference) conforms to garbage collection virtual reference (Phantom Reference) conforms to garbage collection
As an optimization technique during compilation, the Java compiler can choose to assign a null value to the instance, thus marking the instance as recyclable.
Class Animal {public static void main (String [] args) {Animal lion = new Animal (); System.out.println ("Main is completed.");} protected void finalize () {System.out.println ("Rest in Peace!");}}
In the above class, the lion object has never been used after instantiating the row. Therefore, as an optimization measure, the Java compiler can assign lion = null directly after the row is instantiated. Therefore, even before the SOP output, the finalize function can print out 'Rest in output'. We can't prove that this is going to happen because it depends on how JVM is implemented and the memory used by the runtime. However, we can also learn that if the compiler sees that the instance will never be referenced again in the future, it can choose and release the instance space early.
There is a better example of when objects conform to garbage collection. All the generic properties of the instance are stored in registers, which are then accessed and read. Without exception, these values are written back to the instance. Although these values can be used in the future, this instance can still be marked as garbage collection compliant. This is a classic example, isn't it?
When assigned to null, this is a simple example that conforms to garbage collection. Of course, complex situations can be like the points above. This is a choice made by JVM implementers. The goal is to leave as little memory footprint as possible, speed up response time, and improve throughput. To achieve this goal, implementers of JVM can choose a better scheme or algorithm to reclaim memory space during garbage collection.
When the finalize () method is called, JVM releases all synchronization locks on the thread.
GCScope sample program Class GCScope {GCScope t; static int i = 1; public static void main (String args []) {GCScope T1 = new GCScope (); GCScope T2 = new GCScope (); GCScope T3 = new GCScope (); / / No Object Is Eligible for GC t1.t = T2; / / No Object Is Eligible for GC t2.t = T3; / / No Object Is Eligible for GC t3.t = T1 / / No Object Is Eligible for GC T1 = null; / / No Object Is Eligible for GC (t3.t still has a reference to T1) T2 = null; / / No Object Is Eligible for GC (t3.t.t still has a reference to T2) T3 = null; / / All the 3 Object Is Eligible for GC (None of them have a reference. / / only the variable t of the objects are referring each other ina / / rounded fashion forming the Island of objects with out any external / / reference)} protected void finalize () {System.out.println ("Garbage collected from object" + I); iTunes;} class GCScope {GCScope t; static int i = 1; public static void main (String args []) {GCScope T1 = new GCScope () GCScope T2 = new GCScope (); GCScope T3 = new GCScope (); / / No object conforms to GC t1.t = T2; / / No object conforms to GC t2.t = T3; / / No object conforms to GC t3.t = T1; / / No object conforms to GC T1 = null / / No object conforms to GC (t 3.t still has a reference to T1) T2 = null; / / No object conforms to GC (t3.t.t still has a reference to T2) T3 = null; / / all three objects conform to GC (none of them have a reference. / / only the variable t of each object also points to each other, / / forming a circular island of objects without any external references.) } protected void finalize () {System.out.println ("Garbage collected from object" + I); iTunes;} JVM GC algorithm
In determining which memory needs to be reclaimed and when the GC algorithm is used, this paper mainly explains the GC algorithm.
JVM garbage decision algorithm
Common JVM garbage decision algorithms include: reference counting algorithm, reachability analysis algorithm.
Reference counting algorithm (Reference Counting)
The reference counting algorithm determines whether the object can be recycled by judging the number of references of the object.
Add a reference counter to the object, which increases the counter value by 1 whenever there is a reference; when the reference expires, the counter value is subtracted by 1; an object with a counter of 0 at any time can no longer be used.
Advantages: simple, efficient, today's objective-c uses this algorithm.
Disadvantages: it is difficult to deal with circular references, and two objects that reference each other cannot be released. Therefore, the current mainstream Java virtual machines have abandoned this algorithm.
To take a simple example, objects objA and objB both have fields instance, and assign values to objA.instance=objB and objB.instance=objA. In addition, these two objects do not have any references. In fact, the two objects can no longer be accessed, but their reference count is not zero because of mutual references, so the reference counting algorithm cannot tell the GC collector to reclaim them.
Public class ReferenceCountingGC {public Object instance = null; public static void main (String [] args) {ReferenceCountingGC objA = new ReferenceCountingGC (); ReferenceCountingGC objB = new ReferenceCountingGC (); objA.instance = objB; objB.instance = objA; objA = null; objB = null; System.gc (); / / GC}}
Running result
[GC (System.gc ()) [PSYoungGen: 3329K-> 744K (38400K)] 3329K-> 752K (125952K), 0.0341414 secs] [Times: user=0.00 sys=0.00, real=0.06 secs] [Full GC (System.gc ()) [PSYoungGen: 744K-> 0K (38400K)] [ParOldGen: 8K-> 628K (87552K)] 752K-> 628K (125952K), [Metaspace: 3450K-> 3450K (1056768K)], 0.0060728 secs] [Times: user=0.05 sys=0.00, real=0.01 secs] Heap PSYoungGen total 38400K Used 998K [0x00000000d5c00000, 0x00000000d8680000, 0x0000000100000000) eden space 33280K, 3% used [0x00000000d5cf9b200x0000000081400000 0x000000d7c80000) from space 5120K, 0% used [0x000000d7c80000c800c00000000d8180000) to space 5120K, 0% used [0x000000d8180000d81800000x0000d81800000x0000d81800000x000000d81800000x0000000x0000d8680000) ParOldGen total 55872K, used 628K [0x0000000081400000, 0x0000000086980000, 0x00000000d5c00000) object space 87552K, 0% used [0x00000000814000081400000x00000x00000069880000 Metaspace used), capacity 96440000d8180000010x0000d81800000x00000x0000d86800d8680000) ParOldGen total 55872K, used 628K [0x0000000081400000, 0x0000000086980000, 0x00000000d5c00000) object space 87552K, 0% used [0x00000000814000081400000x00000x0000814000081400000x000069880000 Metaspace used), capacity 964400d81800000x0000d81800000x0000d81800000x0000d8180000d8180000d8x0000d8c0000d8c0000d8c0000d8c0000d5cf90000x0000d5cf980000) 0x000000d5cf980000) 0x000000d5cf980000) 0x000000d5cf9000) 0x000000d5cf980000) 0x000000d5cf980000) from space 5120K, 0% used [0x000000d7c80000d7c8000000000x0000D7c800000000
From the running results, the GC log contains "3329K-> 744K", which means that the virtual machine does not recycle the two objects because they refer to each other, indicating that the virtual machine does not judge whether the object is alive by referencing technical algorithms.
Reachability analysis algorithm (root search algorithm)
The reachability analysis algorithm determines whether the object can be recycled by judging whether the reference chain of the object is reachable.
From GC Roots (each concrete implementation has a different definition of GC Roots) as a starting point, searching down the objects they reference can generate a reference tree whose nodes are considered reachable objects and otherwise unreachable.
In the Java language, objects that can be used as GC Roots include the following:
A reference object in the virtual machine stack (the local variable table in the stack frame).
The object referenced by the static property of the class in the method area.
An object referenced by a constant in the method area.
Reference object of JNI (Native method) in the local method stack
The real mark that the object is recyclable should be marked at least twice.
Four kinds of citation
A strong reference is a reference that is common in program code, such as "Object obj = new Object ()". As long as the strong reference exists, the garbage collector will never recycle the referenced object.
Object obj = new Object ()
Soft references are used to describe objects that are still useful but not necessary. Objects associated with soft references will be listed in the scope of recycling for a second collection before a memory overflow exception is about to occur in the system. If there is not enough memory for this collection, a memory overflow exception will be thrown. After JDK1.2, the SoftReference class is provided to implement soft references.
Object obj = new Object (); SoftReference sf = new SoftReference (obj)
Weak references are also used to describe non-essential objects, but they are weaker than soft references, and objects associated with weak references can only survive until the next garbage collection occurs. When the garbage collector works, objects associated with only weak references are recycled, regardless of whether the current memory is sufficient or not. After JDK1.2, the WeakReference class is provided to implement weak references.
Object obj = new Object (); WeakReference wf = new WeakReference (obj)
Virtual references also become ghost references or phantom references, and it is the weakest reference relationship. Whether an object has a false reference or not will not affect its survival time at all, and it is impossible to obtain an object instance through virtual reference. The only purpose of setting a virtual reference association for an object is to receive a system notification when the object is reclaimed by the collector. After JDK1.2, it is provided to the PhantomReference class to implement the virtual reference.
Object obj = new Object (); PhantomReference pf = new PhantomReference (obj); JVM garbage collection algorithm
Common garbage collection algorithms include: tag-removal algorithm, replication algorithm, tag-collation algorithm, generation collection algorithm.
Before introducing the JVM garbage collection algorithm, let's introduce a concept.
Stop-the-World
Stop-the-world means that JVM stops the execution of the application because it is about to execute GC, and this can happen in any GC algorithm. When Stop-the-world occurs, all threads, except those required by GC, wait until the GC task is completed. In fact, GC optimization often refers to reducing the time of Stop-the-world occurrence, so that the system has the characteristics of high throughput and low pause.
Mark-clear algorithm (Mark-Sweep)
The reason why the tag / erase algorithm is the most basic algorithm in several GC algorithms is that the subsequent collection algorithms are based on this idea and improve their shortcomings. The basic idea of the marking / clearing algorithm, like its name, is divided into two stages: "marking" and "clearing": first, all the objects that need to be recycled are marked, and all the marked objects are uniformly reclaimed after the marking is completed.
Tagging phase: the tagging process is actually the process of the reachability analysis algorithm described earlier, traversing all GC Roots objects and marking objects reachable from GC Roots objects, usually in the object's header and recording it as reachable objects.
Cleanup phase: the purging process traverses the heap memory and reclaims an object if it is found that it is not marked as reachable (by reading the object header information).
Deficiency:
The labeling and removal processes are inefficient.
A large number of fragments can be generated, and too much memory fragmentation may prevent memory from being allocated to large objects.
Replication algorithm (Copying)
Divide the memory into two equal blocks, use only one of them at a time, copy the surviving objects to the other when the memory is used up, and then clean up the used memory space again.
Today's commercial virtual machines use this collection algorithm to recycle the new generation, but instead of dividing the memory into two equal blocks, they are divided into a larger Eden space and two smaller Survior spaces, using Eden space and a piece of Survivor each time. During recycling, the objects that are still alive in Eden and Survivor are copied to another Survivor space at once, and finally the Eden and the used Survivor are cleaned. The size ratio of Eden to Survivor for the HotSpot virtual machine defaults to 8:1, ensuring a memory utilization of 90%. If more than 10% of the objects survive each recycling, then a piece of Survivor space will not be enough, and you need to rely on the old age to allocate the guarantee, that is, to borrow the old space.
Deficiency:
Reducing the memory to half of the original memory, wasting half of the memory space, the cost is too high; if you do not want to waste half of the space, you need to have additional space for allocation guarantee, in order to deal with the extreme situation that all objects in the used memory are 100% alive, so it is generally not possible to choose this algorithm directly in the old days.
The replication collection algorithm will carry out more replication operations when the object survival rate is high, and the efficiency will become lower.
Tag-collation algorithm (Mark-Compact)
The tag-collation algorithm is the same as the mark-clearing algorithm, but instead of copying the living object to another piece of memory, it moves the living object to one end of the memory and then directly reclaims the memory beyond the boundary. so it doesn't produce memory fragmentation. The tag-collation algorithm improves the utilization of memory, and it is suitable for the old days when collected objects lived for a long time.
Deficiency:
The efficiency is not high, not only to mark the living objects, but also to sort out the reference addresses of all living objects, which is not as efficient as the replication algorithm.
Generation collection algorithm (Generational Collection)
Generational recycling algorithm is actually a combination of replication algorithm and marking finishing method, which is not really a new algorithm. It is generally divided into: Old Generation and Young Generation. In the old era, there is little garbage to be recycled, and the Cenozoic generation has a lot of memory space to recycle, so different generations use different recycling algorithms to achieve efficient recycling algorithms.
The new generation: because the new generation produces a lot of temporary objects, a large number of objects need to be recycled, so the replication algorithm is the most efficient.
Old age: there are very few recycled objects, and they are all transferred to the old age after several marks, so only a small number of objects need to be recycled, so mark removal or tag finishing algorithm is adopted.
At this point, the study on "what are the basic principles of JVM garbage collection" is over. I hope to be able to solve your doubts. The collocation of theory and practice can better help you learn, go and try it! If you want to continue to learn more related knowledge, please continue to follow the website, the editor will continue to work hard to bring you more practical articles!
Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.
Views: 0
*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.
Continue with the installation of the previous hadoop.First, install zookooper1. Decompress zookoope
"Every 5-10 years, there's a rare product, a really special, very unusual product that's the most un
© 2024 shulou.com SLNews company. All rights reserved.