1. Let’s start with a memory leak example to explain the basic concepts in this section: Example 1: (Singleton causes memory object to be leaked due to inability to release) It can be seen that the ImageUtil tool class is a singleton and references the activity's context. Imagine this scenario: after the application is started, the screen is rotated. After the screen is rotated, the old MainActivity will be destroyed and the new MainActivity will be rebuilt, causing the singleton ImageUtil to getInstance again. Unfortunately, since the instance is no longer empty, ImageUtil will not be rebuilt and will still hold the previous Context, that is, the context of the previous MainActivity instance, which will cause two problems: Functional issue: Exceptions may occur when using ImageUitl to access context-related content (because the current context is not the context of the current activity); Memory leak: The old context is held by a static variable with a longer life cycle, which causes the activity to be unable to release and cause a leak! (Therefore, static variables are very easy to leak memory!) Using the tool, you can see that ImageUtil references MainActivity, causing the MainActivity resident memory to leak. Note: Some concepts and examples in this series are quoted from the Internet. 2. Memory leak, what exactly is the leak object we want to study? First, let's understand the memory allocation strategy required when the program is running: According to the compiler theory, there are three strategies for memory allocation when the program is running, namely static, stack, and heap. Correspondingly, the memory space used by the three storage strategies is mainly the static storage area (also called method area), heap area, and stack area. Their functions are different, and their usage is also different. Static storage area (method area): Memory is allocated when the program is compiled. This memory exists during the entire program execution. It mainly stores static data, global static data and constants. Stack area: When executing a function, storage units for local variables in the function can be created on the stack, and these storage units are automatically released when the function ends. Stack memory allocation operations are built into the processor's instruction set and are very efficient, but the allocated memory capacity is limited. Heap area: also known as dynamic memory allocation. When the program is running, malloc or new is used to apply for memory of any size. The programmer is responsible for releasing the memory with free or delete at the appropriate time (Java relies on the garbage collector). The life span of dynamic memory can be determined by us. If we do not release the memory, the program will release the dynamic memory at the last minute. However, good programming habits are: if a dynamic memory is no longer used, it needs to be released. Next, let's focus on the difference between the heap and the stack: Some basic types of variables and object reference variables defined in a function (indicates that they are local variables) are allocated in the function's stack memory. When a variable is defined in a code block, Java allocates memory space for the variable in the stack. When the scope of the variable is exceeded, Java automatically releases the memory space allocated for the variable, and the memory space can be used for other purposes immediately. Heap memory is used to store all objects created by new (including all member variables of the object) and arrays. The memory allocated in the heap is managed by the automatic garbage collector of the Java virtual machine. After an array or object is generated in the heap, a special variable can be defined in the stack. The value of this variable is equal to the first address of the array or object in the heap memory. This special variable in the stack becomes a reference variable of the array or object. Later, the reference variable in the stack memory can be used in the program to access the array or object in the heap. The reference variable is equivalent to an alias or code name for the array or object. The heap is a discontinuous memory area (because the system uses a linked list to store free memory addresses, which is naturally not continuous). The heap size is limited by the effective virtual memory in the computer system (theoretically 4G for a 32-bit system), so the heap space is more flexible and larger. The stack is a continuous memory area, the size of which is predetermined by the operating system. The stack size under Windows is 2M (or 1M, which is determined at compile time and can be set in VC). For the heap, frequent new/delete will cause a lot of memory fragmentation, reducing program efficiency. For the stack, it is a first-in-last-out queue, with one-to-one correspondence between in and out, no fragmentation, and stable and high operating efficiency. Here is an example of variable storage location 2: in conclusion: The basic data types and references of local variables are stored in the stack, and the referenced object entities are stored in the heap. ——Because they belong to variables in the method, their life cycle ends with the method. All member variables are stored in the heap (including basic data types, references, and referenced object entities) ——Because they belong to classes, class objects will eventually be created and used. Back to our question: What should we pay attention to when it comes to memory leaks? The memory leak we are talking about here is aimed at, and only at, heap memory, which stores the object entities pointed to by the reference. 3. Then the second question is, why does memory leak? In order to determine whether there is a memory leak in Java, we must first understand how Java manages (heap) memory. Java memory management is the problem of object allocation and release. In Java, memory allocation is done by the program, and memory release is done by the garbage collector (GC). Programmers do not need to call functions to release memory, but it can only reclaim the space occupied by objects that are no longer used and are no longer referenced by other objects. Java's memory garbage collection mechanism starts by checking the reference chain from the main running objects of the program (such as static objects/registers/heap memory objects pointed to on the stack, etc.). After traversing once, the above-mentioned unrecyclable objects and the object chains they reference are obtained, forming a collection of unrecyclable objects, and other isolated objects (sets) are collected as garbage. In order to correctly release objects, GC must monitor the running status of each object, including object application, reference, reference, assignment, etc. GC needs to monitor. Monitoring the object status is to release the object more accurately and timely, and the fundamental principle of releasing an object is that the object is no longer referenced. In Java, these useless objects are all reclaimed by GC, so programmers do not need to consider this part of memory leaks. Although we have several functions that can access GC, such as the function System.gc() that runs GC, according to the Java language specification, this function does not guarantee that the JVM's garbage collector will be executed. Because different JVM implementers may use different algorithms to manage GC. Usually the priority of GC threads is lower. There are many strategies for JVM to call GC. Some of them start working when memory usage reaches a certain level, some are timed, some are gentle, and some are interruptive. But generally speaking, we don't need to care about these. At this point, let's take a look at the garbage that needs to be recycled in Java:
The scope of the reference handle p1 is from the definition to the "}". After executing all the codes in the curly braces, the generated Person object will become garbage, because the handle p1 that references this object has exceeded its scope, p1 is invalid and destroyed in the stack, so the Person object on the heap is no longer referenced by any handle. Therefore, person becomes garbage and will be recycled. From the above examples and explanations, we can see a key word: reference. In layman's terms, if A can call and access B, it means that A holds a reference to B, or A is a reference to B, and B's reference count is +1. (1) For example, Person p1 = new Person(); Person objects can be operated through P1, so P1 is a reference to Person; (2) For example, if there is a member variable in class O that is a class I object, we can use the oi method to access the members of the class I object, so o holds a reference to the i object. The GC process is closely related to the reference type of the object. Let's take a look at Java's classification of references: Strong reference, SoftReference, WeakReference, PhatomReference Let's go a step further. What do soft references/weak references here generally do? In the development of Android applications, in order to prevent memory overflow, when dealing with objects that occupy a large amount of memory and have a long declaration cycle, you can try to apply soft reference and weak reference technology. Soft/weak references can be used in conjunction with a reference queue (ReferenceQueue). If the object referenced by the soft reference is reclaimed by the garbage collector, the Java virtual machine will add the soft reference to the reference queue associated with it. This queue can be used to obtain the list of objects with recycled soft/weak references, thereby clearing the invalid soft/weak references for the buffer. Suppose our application will use a large number of default images, such as default avatars, default game icons, etc. These images will be used in many places. If we read the images every time, the reading of files requires hardware operations, which is slow and will lead to low performance. So we consider caching the images and reading them directly from the memory when needed. However, since images take up a large amount of memory space, caching many images requires a lot of memory, which may easily cause OutOfMemory exceptions. At this time, we can consider using soft/weak reference technology to avoid this problem. The following is the prototype of a high-speed buffer: First, define a HashMap to save soft reference objects.
Let's define another method to save the soft reference of Bitmap to HashMap.
After using soft references, the memory space of these cached image resources can be released before the OutOfMemory exception occurs, thereby avoiding the memory reaching the upper limit and avoiding crashes. If you just want to avoid OutOfMemory exceptions, you can use soft references. If you care more about application performance and want to recycle some objects that occupy a large amount of memory as soon as possible, you can use weak references. In addition, you can choose soft reference or weak reference based on whether the object is frequently used. If the object is likely to be used frequently, try to use soft reference. If the object is more likely not to be used, you can use weak reference. Back to our question, why does memory leak? Long-life objects in the heap memory hold strong/soft references to short-life objects. Although the short-life objects are no longer needed, they cannot be recycled because the long-life objects hold their references. This is the root cause of memory leaks in Java. Tencent Bugly, a professional platform for crash monitoring and statistics in China, provides developers with NDK error support, precise problem location, ANR reporting, custom log reporting, intelligent merge analysis and other services. Problems are reported in real time to reduce user churn. |
<<: Experts: Windows Phone is the most secure mobile system
>>: Some security issues in Android development: Activity
Since its establishment in 2013, MINISO has alway...
Want to know how to completely solve it within 30...
As the COVID-19 epidemic continues, most companie...
Noise is a sound that is too loud and can easily ...
What? I woke up and found myself as if I had been...
Retention , as the name suggests, means that user...
So, how to write good code? Good code is easier t...
Did you know? Hail likes to "go mountain roa...
Author: Global Science Mechanisms for coping with...
When talking about the current domestic independe...
Review expert: Li Weiyang, a well-known popular s...
No doubt This is a romance that belongs to the Ch...
In the first half of this year, a document from t...
According to foreign media reports, the German Mi...