Android review Notes directory

  1. Chatter task stack, return stack and lifecycle
  2. The life cycle of chatter activities
  3. Grilled steak a Context
  4. Why not display Dialog using Application Context?
  5. Can OOM be tried catch?

In this paper, a permanent update address: xiaozhuanlan.com/topic/49031…

directory

  • Can OutOfMemoryError be tried?
  • What is the significance of catching OutOfMemoryError?
  • Which chunk of MEMORY in the JVM will not generate OOM?

Can OutOfMemoryError be tried?

This is a classic interview question for a group of small friends, but I believe that many students who encounter this question for the first time should not be able to give an answer immediately, the best way is certainly to test.

Note that each time you click Allocate 20MB, you add 20*1024*1024 to the size of the array. Of course, it is not 20MB. As shown in the following code:

binding.allocate.setOnClickListener {
	try {
		bytes = ByteArray(bytes.size + 1024 * 1024 * 20)
		refreshMemory()
	} catch (e: OutOfMemoryError) {
		binding.oomError.text = "Catch OOM : \n ${e.message}"}}Copy the code

When the seventh click occurs, an OutOfMemoryError occurs and the catch block executes.

Catch OOM : Failed to allocate a 146801680 byte allocation with 25165824 free bytes and 133MB until OOM, target footprint 153948888, growth limit 268435456

So an OutOfMemoryError is a try catch.

Along the way, I drew a mind map to review Java’s exception architecture.

The above image doesn’t list all the exception types, but it Outlines the Java exception inheritance system. All Exception classes inherit from Throwable, which has two direct subclasses Error and Exception.

Exception generally refers to an Exception that can/should be caught and handled. Its two direct subclasses, IOException and RuntimeException and their subclasses, are some of the bugs we often encounter in code. RuntimeException is an exception that may occur during the execution of the program. We may not catch RuntimeException, but it may bring Crash cost, but too many exceptions are not conducive to exposure and debugging of exceptions. In the development process, we should expose problems in time. Exceptions other than runtimeExceptions can be collectively referred to as non-runtime or checked exceptions, which must be caught or an error will be reported at compile time.

Error generally refers to an abnormal, serious system Error that should not be caught.

Going back to the parents of OutOfMemoryError,

OutOfMemoryError <- VirtualMachineError <- Error

OutOfMemoryError is an Error, and errors should not be caught. So what is the point of catching OutOfMemoryError?

What is the significance of catching OutOfMemoryError?

In most cases it doesn’t make much sense, and I’m sure you’ve written very little catch OOM code in your development.

If you use capturing OOM as a means of dealing with OOM, it is definitely not appropriate. There is no guarantee that your catch code is the cause of the OOM, maybe it was the straw that broke the camel’s back, and there is no guarantee that your catch block won’t trigger the OOM again.

I’ve never written code to capture the OOM, but I came across it in the Android source code. The view.java buildDrawingCacheImpl() method has this code:

try {
    bitmap = Bitmap.createBitmap(mResources.getDisplayMetrics(),
                        width, height, quality);
    bitmap.setDensity(getResources().getDisplayMetrics().densityDpi);
    if (autoScale) {
        mDrawingCache = bitmap;
     } else {
         mUnscaledDrawingCache = bitmap;
     }
     if (opaque && use32BitCache) bitmap.setHasAlpha(false);
} catch (OutOfMemoryError e) {
    // If there is not enough memory to create the bitmap cache, just
    // ignore the issue as bitmap caches are not required to draw the
    // view hierarchy
    if (autoScale) {
        mDrawingCache = null;
    } else {
        mUnscaledDrawingCache = null;
}
mCachingFailed = true; .Copy the code

The buildDrawingCacheImpl() method basically generates a Bitmap cache for the current View. When building a Bitmap object, if the OOM is captured, the Bitmap Cache is discarded because the Bitmap Cache is not required to be present during the View drawing process. So there’s no need to throw the OOM, just catch it yourself.

Having a backstop strategy when you know for sure that OOM is possible is probably the only point of capturing OOM. If you have any other weird tricks, feel free to add them in the comments section.

Which chunk of MEMORY in the JVM will not generate OOM?

Finally, an interview question I’ve had, which memory block in the JVM won’t get OOM?

I didn’t think it through during the interview, so I came back and read “Understanding the Java Virtual Machine”. But almost all questions about the JVM can be answered in this book. Chapter 2: Java Memory Regions and memory overflow Exceptions.

During the execution of Java programs, the Java VIRTUAL machine divides the managed memory into several data areas, as shown in the following figure:

Java virtual machine stack. As each method is executed, the Java virtual machine stack synchronously creates a stack frame to store information about local variables, operand stacks, dynamic connections, method exits, and so on. Each method is called until the execution is complete, corresponding to a stack frame in the virtual machine stack from the stack to the stack process.

StackOverflowError is thrown if the stack depth requested by the thread is greater than the depth allowed by the virtual machine. If the Java virtual machine stack supports dynamic scaling, OutOfMemoryError will be thrown if sufficient memory cannot be allocated during stack scaling.

Local method stack. Native methods used by virtual machines. The Java Virtual Machine Specification does not enforce any language, usage, or data structure for methods in the local method stack, so specific virtual machines are free to implement it as needed. Hotspot combines the local method stack with the virtual machine stack.

The local method stack also throws StackOverflowError and OutOfMemoryError when the stack depth overflow and stack extension fail, respectively.

The Java heap. An area of memory shared by all threads, created when the virtual machine is started. The sole purpose of this memory area is to hold object instances, and “almost” all object instances in the Java world are allocated memory here. The Java Virtual Machine Specification describes the Java heap as “all object instances and arrays should be allocated on the heap.”

The Java heap is in a physically discontinuous memory space, but logically it should be treated as continuous. But for large objects (typically groups of objects), most virtual machine implementations will most likely require contiguous memory space for simplicity of implementation and storage efficiency.

The Java heap can be implemented as either a fixed size or extended. The Java virtual machine will throw an OutOfMemoryError if there is no memory in the Java heap to complete the instance allocation and the heap cannot be extended.

Methods section. A method area is an area of memory shared by each thread that stores data such as type information that has been loaded by the virtual machine, constants, static variables, and code caches compiled by the just-in-time compiler.

Although the Java Virtual Machine Specification describes the method area as a logical part of the heap, it has a nickname called “non-heap” to separate it from the Java heap.

Hotspot was originally designed to extend the generational design of the garbage collector to the method area, or to implement the method area using permanent generations, allowing Hotspot’s GC to manage this part of memory as well as the Java heap, but making Java applications more prone to memory overflow problems. In JDK 8, the concept of permanent generations was scrapped completely.

OutOfMemoryError is thrown if the method area cannot meet the requirements of the new memory allocation.

Run-time constant pool. Part of the method area. The constant pool table of the Class file, used to hold various literals and symbolic references generated at compile time, which will be removed from the runtime constant pool by the method method after the Class is loaded.

The runtime constant pool is dynamic, and new constants can also be put into the pool at run time, such as string.intern ().

The constant pool is limited by the method area and raises an OutOfMemoryError when no more memory can be allocated.

The only area where the Java Virtual Machine Specification does not specify any OutOfMemoryError cases is the program counter. The Program Counter Register is a small memory space that can be thought of as a line number indicator of the bytecode being executed by the current thread. If the thread is executing a Java method, this counter records the address of the virtual machine bytecode instruction being executed. If the Native method is being executed, this counter value should be null.

The last

This is the fifth article in this column. Most of the writing materials come from my friends. I also maintain a document of interview questions, but considering that sharing documents can be confusing, there may be other ways to share them later.