Android memory and performance optimization Summary

Source: Internet
Author: User
Tags integer division java reference

Android memory and performance optimization Summary

1. Instant Compilation (Just-in-time Compilation, JIT), also known as Dynamic Translation (Dynamic Translation), is a way to translate bytecode into machine code at runtime, this improves the performance of bytecode compiling languages. The two runtime theories at the early stage of real-time compilation are bytecode compilation and dynamic compilation. Android uses the Dalvik virtual machine as an interpreter. The new version (Android2.2 +) will be implemented by the JIT compiler. Performance tests show that new versions in multiple tests are about six times higher than earlier versions.

2,

Just like there is no free lunch in the world, and there are no free objects in the world. Although gc creates a temporary object pool for each thread, it can reduce the cost of object creation, but the cost of memory allocation is always higher than that of memory allocation. If you allocate the object memory in the user interface loop, it will lead to periodic garbage collection, and the user will feel that the interface is as choppy. Therefore, unless necessary, try to avoid the instance of the object as much as possible. The following example will help you understand this principle: When you extract a string from user input data, try to use the substring function to obtain a substring of the original data, instead of creating another copy for the substring. In this way, you have a new String object, which shares a char array with the original data. If you have a function that returns a String object, and you know exactly that the String will be appended to a StringBuffer, change the parameter and implementation method of this function, directly append the result to StringBuffer, instead of creating a short-lived temporary object.

A more extreme example is to divide a multi-dimensional array into multiple one-dimensional arrays:

The int array is better than the Integer array, which also summarizes the basic fact that two parallel int arrays provide much better performance than the array of (int, int) objects. Similarly, this is intended for a combination of all basic types. If you want to use a container to store (Foo, Bar) tuples, try to use two separate Foo [] arrays and Bar [] arrays, which must be equal to (Foo, Bar) array efficiency is higher. (There is also an exception, that is, when you create an API to allow others to call it. At this time, you should pay attention to the design of the API interface and sacrifice a little speed. Of course, you still need to improve the code efficiency as much as possible within the API)

In general, it is to avoid creating short-lived temporary objects. Reduce the creation of objects to reduce the garbage collection, and thus reduce the impact on user experience.

3. Static methods instead of Virtual Methods

If you do not need to access the field of an object and set the method to static, the call will be accelerated by 15% to 20%. This is also a good practice, because you can see from the method declaration that calling this method does not need to update the state of this object.

4. Avoid internal Getters/Setters

5. cache members locally

Accessing member variables is much slower than accessing local variables. The following code:

For (int I = 0; I
 
  

It is best to change it to this:

int count = this.mCount;Item[] items = this.mItems;for(int i =0; i < count; i++)  {       dumpItems(items);}

Another similar principle is: Never call any method in the second condition of. As shown in the following method, the getCount () method is called every time a loop is executed, which is much more overhead than saving the result in an int.

Similarly, if you want to access a variable multiple times, you 'd better create a local variable for it first, for example:

Here, the member variable mScrollBar is accessed four times. If it is cached locally, the four member variable accesses will become four more efficient stack variable accesses.

In addition, the efficiency of method parameters is the same as that of local variables.

6. Use the static final modifier for Constants

Let's take a look at the Declaration of the two paragraphs before the class:

static int intVal = 42;static String strVal = "Hello, world!"

It will generate a method of initialization class called clinit. This method will be executed when the class is used for the first time. The method will assign 42 to intVal, and then assign a reference pointing to a common table in the class to strVal. When these values are used in the future, they will be found in the member variable table. Let's make some improvements and use the keyword "final:

Static final int intVal = 42; static final String strVal = "Hello, world! "; Currently, the clinit method is no longer required for classes, because constants are directly saved to class files during member variable initialization. The code that uses intVal is directly replaced with 42, and strVal points to a String constant instead of a member variable.

Declaring a method or class as final will not improve the performance, but will help the compiler optimize the code. For example, if the compiler knows that a getter method will not be overloaded, the compiler will use inline calls to it.

You can also declare the local variable as final, which will not improve the performance. Using "final" can only make the local variables look clearer (but sometimes this is required, for example, when using anonymous internal classes ).


7,

Use improved For loop syntax

Improved for loop (sometimes called for-each loop) can be used in collection classes and arrays that implement the iterable interface. In the collection class, the iterator asks the interface to call the hasNext () and next () methods. In ArrayList, handwritten counting loop iterations are three times faster (whether JIT exists or not), but in other collection classes, the improved for loop method and iterator have the same efficiency. The following shows how to access arrays in a set:

static class Foo {        int mSplat;    }    Foo[] mArray = ...    public void zero() {        int sum = 0;        for (int i = 0; i < mArray.length; ++i) {            sum += mArray[i].mSplat;        }    }    public void one() {        int sum = 0;        Foo[] localArray = mArray;        int len = localArray.length;          for (int i = 0; i < len; ++i) {            sum += localArray[i].mSplat;        }    }    public void two() {        int sum = 0;        for (Foo a : mArray) {            sum += a.mSplat;        }}}  

In zero (), each loop accesses two static member variables to obtain the length of an array.

In one (), all member variables are stored locally.

Two () uses the foreach syntax introduced in java1.5. The compiler saves the array reference and length to the local variable, which is very good for accessing array elements. However, the compiler will also generate an additional storage operation on local variables (access to variable a) in each loop, which will be 4 bytes more than one, the speed is a little slower.

8,

Avoid floating point number

Generally, in Android devices, floating point numbers are twice slower than integer types, this is true in the Nexus One with FPU and JIT compared to the G1 without FPU and JIT (the absolute speed difference between arithmetic operations between the two devices is about 10 times) in terms of speed, in modern hardware, float and double are no different. More broadly speaking, double is two times larger. On a desktop, because there is no space problem, double has a higher priority than float. However, even if it is an integer, some chips have hardware multiplication, but there is no division. In this case, integer division and modulo calculation are implemented through software, just like when you design a Hash table or do a lot of arithmetic operations, for example, a/2 can be changed to a * 0.5.

9,

Reduce Unnecessary global variables

Avoid using static member variables to reference instances that consume too much resources, such as Context. Android provides a sound message transmission mechanism (Intent) and task model (Handler). It can prevent unnecessary global variables through transmission or event.

10,

Four Java reference methods

In JDK 1.2, object references are classified into four levels, so that the program can control the object lifecycle more flexibly. The four levels are from high to low: strong reference, soft reference, weak reference, and virtual reference.

I. StrongReference)

Strong references are the most common references. If an object has a strong reference, the garbage collector will never recycle it. When the memory space is insufficient, the Java Virtual Machine would rather throw an OutOfMemoryError to terminate the program abnormally, and does not recycle strongly referenced objects at will to solve the problem of insufficient memory.

Ii. SoftReference)

If an object only has soft references, the memory space is sufficient and the garbage collector will not recycle it. If the memory space is insufficient, the memory of these objects will be recycled. The object can be used by programs as long as the garbage collector does not recycle it. Soft references can be used to implement memory-sensitive high-speed cache.

Iii. WeakReference)

When the Garbage Collector thread scans the memory area under its jurisdiction, its memory will be recycled no matter whether the current memory space is sufficient or not. However, since the garbage collector is a thread with a low priority, it may not soon find objects with weak references.

Iv. PhantomReference)

As the name suggests, it is just a virtual setting. Unlike other references, virtual references do not determine the object lifecycle. If an object only holds a virtual reference, it is the same as no reference and may be recycled by the garbage collector at any time. Understanding and mastering the reference methods in these 4 fields, selecting the appropriate object application method is helpful for memory recovery.

See http://blog.csdn.net/feng88724/article/details/6590064 for details

Cache is often used in Android:
A. Thread Pool
B. Android image cache, Android image Sdcard cache, and data prefetch Cache
C. Message Cache
Use handler. obtainMessage to reuse the previous message, as shown below:

1 Handler. sendMessage (handler. obtainMessage (0, object ));

D. ListView Cache

E. Network Cache
The database caches http response and determines the Cache expiration time based on the Cache-Control domain in the http header information.
F. file IO Cache
The input stream with a cache policy is used. BufferedInputStream replaces InputStream, BufferedReader replaces Reader, and BufferedReader replaces BufferedInputStream. This applies to files and network I/O.
G. layout Cache
H. Other data caches that require frequent access or one access consume a large amount of data

(2) Data Storage Optimization
Including selection of data types and data structures.
A. Data Type Selection
String concatenation replaces String with StringBuilder, and replaces StringBuffer with StringBuilder without concurrency. If you have a general understanding of the length of a string, such as about 100 characters, you can directly specify the initial size in new StringBuilder (128) to reduce the allocation when the space is insufficient.
Processing of 64-bit data such as long double is slower than processing of 32-bit data such as int.
SoftReference and WeakReference are more conducive to system garbage collection than normal applications.
The final type is stored in the constant area for higher Read efficiency.
LocalBroadcastManager replaces normal BroadcastReceiver with higher efficiency and security.

B. Data Structure Selection
Common Data Structure options include:
In the selection of ArrayList and sort list, ArrayList takes a faster value based on the index. The sort list occupies more memory, the random insertion and deletion speed, and the expansion efficiency is higher. ArrayList is generally recommended.
Select ArrayList, HashMap, LinkedHashMap, and HashSet. The query speed of hash data structures is better. ArrayList stores ordered elements. HashMap is the key-value pair data structure. LinkedHashMap can remember the hashMap added to the order, repeated elements are not allowed in HashSet.
Select HashMap and WeakHashMap. The elements in WeakHashMap can be automatically recycled by the system garbage collector when appropriate, so it is suitable for use in memory-intensive scenarios.
Collections. The choice of synchronizedMap and ConcurrentHashMap, ConcurrentHashMap is a subdivision lock, the lock granularity is smaller, and the concurrency performance is better. Collections. synchronizedMap is the object lock. It is more convenient to add functions to implement lock control.

Android also provides some data types with better performance, such as SparseArray, SparseBooleanArray, SparseIntArray, and Pair.
The data structure of the Sparse series is a special processing case where the key is int. It adopts binary search and simple array storage, and does not require the overhead of generic conversion, which is superior to that of Map. But I don't quite understand why the default capacity is 10. Have you done data statistics? Or do you still have to consider these things when writing 16, we recommend that you set the initial value based on your possible capacity.

(3). Algorithm Optimization
This topic is relatively large and requires detailed analysis of specific issues. Do not use algorithms with O (n * n) time complexity or higher, and change the available space for time when necessary.
Consider hash and binary for query, and do not use recursion as much as possible. You can learn from structured algorithms or Microsoft or Google interview questions.

(4). JNI
Android applications are mostly developed in Java. the JIT compiler of Dalvik is required to run the code at the cost of Java bytecode conversion. The local code can be directly executed by the Device Manager, saving the intermediate steps, therefore, the execution speed is faster. However, it requires overhead to switch from the Java space to the local space, and the JIT compiler can also generate optimized local code. Therefore, poor local code may not necessarily have better performance.
This optimization point will be described in a separate blog later.

(5). Logical Optimization
This is different from the algorithm, mainly to clarify the program logic and reduce unnecessary operations.

(6). Demand Optimization
This will not be said. For the performance problems that may arise from sb requirements, we can only say that as a qualified programmer, we should not only be the performer, but also learn to say NO. However, you cannot use this interface to fool the product manager.

2. asynchronous, using multithreading to improve TPS
Take full advantage of multi-core Cpu and use threads to handle intensive computing, IO, and network operations.
For more information about multithreading, see:
In Android applications, due to system ANR restrictions, the master thread timeout operation may be put into another working thread. Handler can be used to interact with the main thread in the work thread.

3. Advance or delay operations to increase TPS by mistake
(1) Delayed operations
Delay is not applicable to time-consuming operations in response-sensitive functions such as Activity, Service, and BroadcastReceiver lifecycles.
In Java, you can use ScheduledExecutorService for delayed operations. Timer. schedule is not recommended;
In addition to ScheduledExecutorService, Android also supports some delay operations, such
Handler. postDelayed, handler. postAtTime, handler. sendMessageDelayed, View. postDelayed, and AlarmManager timing.

(2) advance operations
For the time-consuming operations that are called for the first time, they can be put into initialization in advance. For example, obtain the wallpaper wallpaperManager. getDrawable ();

4. Network Optimization
The following are some principles that clients and servers need to comply with in network optimization:
A. The image must be cached. It is best to make image adaptation based on the model.
B. httptimeout must be added for all http requests.
C. api interface data is returned in json format, instead of xml or html
D. Check whether the request results are cached Based on the Cache-Control domain in the http header.
E. Reduce the number of network requests and merge requests on the server.
F. Reduce the number of redirection times
G. The response time of the api server cannot exceed 100 ms.
Google is working on a project to speed mobile Web pages down to 1 second, focusing on https://developers.google.com/speed/docs/insights/mobile



Android Performance Optimization Method
Http://mobile.51cto.com/abased-410785.htm

For some Android projects, the main cause of performance bottleneck is the memory management mechanism of Android. Currently, mobile phone manufacturers are stingy with RAM and are very sensitive to the impact of RAM on the Performance of software fluency, in addition to optimizing the heap memory allocation of the Dalvik virtual machine, we can also forcibly define the memory size of our software. We use the Dalvik provided by dalvik. system. the following example uses the VMRuntime class to set the minimum heap memory:

   
  
  1. private final static int CWJ_HEAP_SIZE = 6* 1024* 1024 ;



   
  
  1. VMRuntime.getRuntime().setMinimumHeapSize(CWJ_HEAP_SIZE);

// Set the minimum heap memory size to 6 MB. Of course, for memory compression, manual GC interference can also be performed.


Bitmap sets the image size to avoid memory overflow OutOfMemoryError.
★When bitmap is used in android, memory overflow is very easy. The following error is reported: Java. lang. OutOfMemoryError: bitmap size exceeds VM budget

● This section is mainly added:

   
  
  1. BitmapFactory.Options options = new BitmapFactory.Options();
  2. options.inSampleSize = 2;



● Eg1: (image retrieval through Uri)

   
  
  1. Private ImageView preview;
  2. BitmapFactory. Options options = new BitmapFactory. Options ();
  3. Options. inSampleSize = 2; // The image width and height are 1/2 of the original image, that is, the image is 1/4 of the original image.
  4. Bitmap bitmap = BitmapFactory. decodeStream (cr
  5. . OpenInputStream (uri), null, options );
  6. Preview. setImageBitmap (bitmap );


The above code can optimize memory overflow, but it only changes the image size and does not completely resolve the memory overflow.
● Eg2: (image removal Through PATH)

   
  
  1. Private ImageView preview;
  2. Private String fileName = "/sdcard/DCIM/Camera/2010-05-14 16.01.44.jpg ";
  3. BitmapFactory. Options options = new BitmapFactory. Options ();
  4. Options. inSampleSize = 2; // The image width and height are 1/2 of the original image, that is, the image is 1/4 of the original image.
  5. Bitmap B = BitmapFactory. decodeFile (fileName, options );
  6. Preview. setImageBitmap (B );
  7. FilePath. setText (fileName );



★There are also some Performance Optimization Methods for Android:
● In terms of memory, you can refer to the Android heap memory and customize the size and optimize the heap memory allocation of the Dalvik virtual machine.

● In terms of basic types, Because Java does not have actual pointers, NDK must be used for sensitive operations. What is interesting about this is that Google launches NDK to help game developers. For example, the support of OpenGL ES has been significantly improved, and it is necessary to operate the GUI on the local code.

● Image object optimization. Here we will talk about the destruction of Bitmap objects on Android. You can use the recycle () method to display and let GC reclaim a Bitmap object, the following method can be used for a non-Bitmap, as shown in figure

   
  
  1. If (bitmapObject. isRecycled () = false) // if not recycled
  2. BitmapObject. recycle ();



● Currently, the system is relatively mentally retarded in supporting animation, which can be used for the interim Effect of regular applications. However, for games, normal artists may be used to unified GIF Processing, currently, the Android system can only preview the first frame of a GIF. You can read Resources in the GIF89 format by using a thread and a self-writing parser in j2s.

● For most Android phones without too many physical buttons, we may need to imagine a good gesture recognition GestureDetector and gravity sensing for control. We usually need to consider noise reduction for misoperation problems.

You can also customize the size of the Android heap memory.

For some large Android projects or games, there is no problem in algorithm processing. The main cause of the performance bottleneck is the memory management mechanism of Android. Currently, mobile phone manufacturers are stingy with RAM, for the smoothness of software, RAM is very sensitive to the performance impact. Apart from the optimization of the heap memory allocation of the Dalvik Virtual Machine mentioned in the Android Development Network last time, we can also forcibly define the memory size of our software. We use the Dalvik provided by dalvik. system. the following example uses the VMRuntime class to set the minimum heap memory:

   
  
  1. private final static int CWJ_HEAP_SIZE = 6* 1024* 1024 ;



   
  
  1. VMRuntime.getRuntime().setMinimumHeapSize(CWJ_HEAP_SIZE);

// Set the minimum heap memory size to 6 MB. Of course, for memory compression, manual GC interference can also be performed. We will refer to the specific application next time.

Optimize heap memory allocation of Dalvik virtual machines

For the Android platform, the Dalvik JavaVM used by its hosting layer can be optimized from the current performance, for example, when developing large game or resource-consuming applications, we may consider Manual Interference with GC and use dalvik. system. the setTargetHeapUtilization method provided by the VMRuntime class can improve the processing efficiency of the program heap memory. Of course, we can refer to the open-source project for specific principles. Here we only talk about the usage: private final static floatTARGET_HEAP_UTILIZATION = 0.75f; VMRuntime can be called during onCreate. getRuntime (). setTargetHeapUtilization (TARGET_HEAP_UTILIZATION.

[Edit recommendations]


Android Performance Optimization Methods
Http://blog.csdn.net/yugui865/article/details/10211595

1. Use hardware acceleration to add android: hardwareAccelerated = "true" to the application in androidmanifest. xml ". However, this can be used only in android 3.0.

2. Set the cache attribute in View. setDrawingCache to true.

3. Optimize your layout. Use the layoutopt command in the tools directory of the Android sdk to check whether your layout needs optimization.

4. dynamically load the View. Use ViewStub to avoid some views that are not often referenced for a long time.

5. Set the background image of the Window in Acitivity to null. GetWindow (). setBackgroundDrawable (null); is the default background of android empty.

6. Use The layout layers are optimized. Use To share the layout.

7. View Heap size

8. Use TraceView to view trace function calls. Targeted optimization.

9. Use of cursor. However, you must manage cursor. Do not close cursor every time you open it, because it takes a lot of time to close Cursor. Cursor. require is used to refresh cursor.

10. Use a circular Buffer (the Linked List data structure can be used ). You can set an upper limit on the length of a linked list and update the content of the circular Buffer continuously based on changes in gestures.

11. Use SurfaceView to refresh the UI in the sub-thread to avoid processing and drawing gestures in the same UI thread (common views do this ).

12. Use JNI to place time-consuming processing on the c/c ++ layer.

13. For some operations that can use files, try to use file operations. File Operations are about 10 times faster than database operations.

14. Lazy loading and caching mechanisms. Start a new thread instead of the UI thread for time-consuming operations to access the network.


Memory leakage caused by uncleanup of objects in the collection
We usually add some object references to the collection. When we don't need this object, we didn't clear its references from the collection, so this set will become larger and larger. If the set is static, the situation is more serious.


. Static keyword
When a member variable of a class is declared static, it belongs to the class rather than the object. If we declare a large resource object (such as Bitmap and context) as static, these resources will not be recycled with the collection of objects,
So be careful when defining member variables using the static keyword.

Use a conservative Service

If your application needs to use the service to execute business functions in the background, unless it is ongoing activities (for example, requests data from the server every several seconds) otherwise, do not keep it running in the background. in addition, when your service execution is complete but the stop fails, be careful about the memory leakage caused by the service.

When you start a service, the system always gives priority to service running. this results in low memory application efficiency because the memory used by the Service cannot do other tasks. it also reduces the number of LRU cache processing that the system keeps, reducing the switching efficiency of different apps. currently, when all services are running, the memory is insufficient and the system is not running properly. If the system gets stuck, the system restarts continuously.

The best way is to use IntentSevice to control the service life cycle. When you start a task with intent, the service will automatically stop after all the work is completed.

In android applications, using a resident service is one of the worst memory management methods when you do not need to use a resident service to execute business functions. therefore, do not use services to keep your applications running. this not only increases the risk of application running because of memory restrictions, but also causes the user to detach the application after discovering these abnormal behaviors.

The memory is released when the view is hidden.

When you jump to different applications and your view is no longer displayed, you should release the resources occupied by the application view. in this case, releasing the resources occupied can significantly increase the cache processing capacity of the system and directly affect the user experience quality.

When the onTrimMemory () callback method of the current Activity class is implemented, the user will be notified when leaving the view. this method can be used to listen to the TRIM_MEMORY_UI_HIDDEN level. When your view elements are hidden from the parent view, release the resources occupied by the view.

Note that only when all view elements of your application become hidden can your application receive TRIM_MEMORY_UI_HIDDEN of the onTrimMemory () callback method. this method is different from the onStop () callback method. This method is triggered only when the Activity instance changes to the hidden state or when a user moves to another activity in the application. therefore, although you have implemented onStop () to release activity resources, such as network connections or unregistered broadcast recipients, you should wait until you receive onTrimMemory (TRIM_MEMORY_UI_HIDDEN) otherwise, the resources occupied by the view should not be released. it can be confirmed that if the user enters your application from another activity through the back key, the view resource will remain available and can be used to quickly restore the activity.

Release memory when memory resources are insufficient

The onTrimMemory () callback method at any stage of the application lifecycle tells you that the device memory is getting lower and lower. You can release resources based on the memory shortage level pushed by this method.

  • TRIM_MEMORY_RUNNING_CRITICAL

    The application is running and will not be killed. The memory used by the device is relatively low, and the system level will kill some other cache applications.

    • TRIM_MEMORY_RUNNING_LOW

      The application is running and will not be killed. The memory available to the device is very low, and unused resources can be released to Improve the Performance (which will directly affect the performance of the program)

      • TRIM_MEMORY_RUNNING_CRITICAL the application is running, but the system has killed most cached applications. You must release resources that are not critical. If the system cannot recycle enough running memory, the system will clear all cached applications and kill active applications.

        Also, when your application is being cached by the system, you can use the onTrimMemory () callback method to receive the following memory levels:

        • TRIM_MEMORY_BACKGROUND

          The system is running in low memory and your application is in the initial stage of caching the Application List. although your application is not at high risk of being killed, the system has begun to clear other applications in the cache list, therefore, you must release the resources so that your application remains in the list so that the user can quickly restore to use your application again.

          • TRIM_MEMORY_MODERATE

            The system is in a low-memory running state and your application is in the intermediate stage of the cache application list. If the system runs the memory and receives the limit, your application may be killed.

            • TRIM_MEMORY_COMPLETE

              The system is in a low-memory running state. If the system does not have memory to recycle your application, it will be the first to be killed. You must release all non-critical resources to restore the application.

              Because onTrimMemory () is added to the android api of Level 14, the onLowMemory () method should be used in earlier versions. This method is roughly equivalent to TRIM_MEMORY_COMPLETE event.

              Note: When the system begins to clear applications in the cache application list, although the main working mechanism of the system is bottom-up, however, the system will also get more memory by killing applications that consume large memory, therefore, consuming less memory in the cache application list will lead to a larger opportunity to be retained so that users can quickly recover when they use it again.

              Check the memory size.

              As mentioned above, different android device systems have different running memory, so the size of different application heap memory is different. you can call the getMemoryClass () function in ActivityManager to obtain the available memory size of the current application in megabytes. If you want to obtain the maximum memory size, an OutOfMemoryError occurs.

              In a special case, when the largeHeap attribute value is set to "true" in the tag in the manifest file, the current application can obtain the maximum heap memory allocated by the system. if you set this value, you can use the getLargeMemoryClass () function of ActivityManager to obtain the maximum heap memory.

              Then, only a small number of applications consume a large amount of heap memory (such as large photo editing applications ). you never need to use a large amount of memory because you have consumed a large amount of memory and must fix it quickly, you must use it because you know that all the memory has been allocated and you must keep the current application and it will not be cleared. even when your application needs to consume a large amount of memory, you should avoid this requirement as much as possible. after a large amount of memory is used, when you switch between different applications or perform other similar operations, because a long period of memory recovery will cause the system performance to decline, which will gradually damage the user experience of the entire system.

              In addition, not all devices with large memory are the same. when running on a device with a running memory limit, the large memory is the same as the normal heap memory. therefore, if you need a large memory size, you need to call the getMemoryClass () function to check the normal heap memory size and maintain the memory usage under the normal heap memory as much as possible.

              Avoid wasting memory in bitmaps

              When you load bitmap, you need to maintain its memory size based on the resolution to maximize the resolution of the current device. If the downloaded source image is of high resolution, you need to stretch it. be careful when the bitmap resolution increases and the occupied memory is also increased, because it increases the memory usage according to the size of x and y.

              Note: For Android 2.3.x (api level 10) or lower, the bitmap object size is always displayed in the memory regardless of the image resolution, the actual pixel data is stored in the memory of the underlying native (c ++ memory ). because the memory analysis tool cannot track native memory status, it becomes very difficult to debug bitmap memory allocation. however, starting from Android 3.0 (api level 11), the memory data of bitmap objects is allocated in the heap memory of the Dalvik virtual machine where the application is located, improving the recovery rate and the possibility of debugging. if you find that the bitmap object occupies the same memory size in the old version, switch the device to System 3.0 or above for debugging.

              Use the Optimized Data container

              Use the Optimized Data containers of the Android framework, such as SparseArray, SparseBooleanArray, and LongSparseArray. the implementation of the traditional HashMap in memory is very inefficient because it needs to establish a ing relationship for each item in the memory of the map. in addition, the SparseArray class is very efficient because it avoids keys and some values in the system that require automatic autobox sealing.

              Know memory overhead

              During each phase of your application design, you must carefully consider the memory costs and overhead brought about by the languages and libraries you use. normally, seemingly harmless results in huge overhead. The following is an example:

              • When enum becomes a static constant, the memory overhead is more than twice as high as normal. In android, you must strictly avoid enumeration.
              • Each class in java (including an anonymous internal class) uses approximately 500 bytes
              • Each class instance occupies 12 to 16 bytes in the running memory (RAM)
              • When you add a single data item to a hashmap, You need to allocate memory for the additional items, occupying a total of 32 bytes.

                When many unnecessary classes and objects are used, the complexity of heap memory analysis is increased.

                Beware of abstract code

                Generally speaking, simple abstraction is a good programming habit, because a certain degree of abstraction can provide code scalability and maintainability. however, abstraction brings significant overhead: More code needs to be executed, and the code needs to be mapped to the memory for a longer period of time with more running memory, therefore, if the abstract does not bring significant results, try to avoid it.

                Use nano Protocol buffers as serialized data

                Protocol Buffers is a data description language developed by Google. Similar to XML, it can serialize structured data. but it is smaller, faster, and simpler. if you decide to use it as your data, you must always use nano protocol buffer in your client code, because normal protocol buffer will generate extremely redundant code, in your application, there are many problems: increasing the memory usage, increasing the size of the apk file, slow execution speed, and fast loading some restricted symbols into the dex package.

                Avoid using the dependency injection framework whenever possible

                Using the dependency injection frameworks such as Guice and RoboGuice will be very attractive, it allows us to write some simpler Code and provide an adaptive environment for useful testing and other configuration changes. however, these frameworks scan your code through annotations to execute a series of initialization operations, but these will also map a lot of code that we don't need to be in the memory. the mapped data will be allocated to the clean memory, which will not be used for a long time after being put into the memory, resulting in a large amount of memory waste.

                Exercise caution when using external dependent Libraries

                Many external dependent libraries are not written in the mobile environment, which is very inefficient when these libraries are used in mobile applications. therefore, when you decide to use an external library, you need to take on the porting and maintenance burden brought about by optimization for the external library of mobile applications. in the early stage of the project plan, we need to analyze the authorization conditions, code volume, and memory usage of the class library to determine whether to use the library.

                It is said that the Library specially designed for android has potential risks, because each library does different things. for example, one database may use nano protobuf and the other database uses micro protobuf. Now there are two different protobuf implementations in your application. this will lead to different logs, analyses, image loading frameworks, caches, and other unpredictable events. proguard will not save your features because all low-level api dependencies require the features contained in the libraries on which you are dependent. when you use an activity inherited from an external library, this is especially a problem (because it often produces a lot of Dependencies ). libraries need to use reflection (this is common because you have to spend a lot of time adjusting ProGuard to make it work.

                Be careful not to fall into the trap of using dozens of dependent libraries to implement one or two features; do not introduce a lot of unnecessary code. at the end of the day, when you do not find an implementation that meets your requirements, the best way is to create your own implementation.

                Optimize Overall Performance

                In addition to the above situations, the CPU performance and user interface can be optimized, and the memory can be optimized.

                Use code obfuscation to remove unnecessary code

                The code obfuscation tool ProGuard removes unused code and renames classes through semantic fuzzy, narrowing down fields and methods to optimize and confuse your code. you can use it to make your code more concise, with a smaller number of RAM ing pages.

                Use the signature tool to sign the apk File

                If you do not perform any subsequent processing (including signing based on your certificate) after building the apk, you must run the zipalign tool to re-sign your apk, if you do not do this, your application will use more memory, because something like a resource will no longer be mapped from the apk (mmap ).

                Note: goole play store does not accept unsigned apk

                Analyze your memory usage

                Use adb shell dumpsys meminfo + package name and other tools to analyze the memory usage of your application in various lifecycles. This will be reflected in subsequent blog posts.

                Use multi-process

                A more advanced technology can manage the memory in the application. The separation component technology can divide the memory of a single process into multi-process memory. this technology must be used with caution and most applications will not run multiple processes, because if you do not operate properly, it will waste more memory instead of reducing memory. it is mainly used for backend and front-end applications that can independently take charge of different services.

                It is more appropriate for your application to use multi-process processing when you build a music player application and play music from a service for a long time. if the entire application has only one process, but the current user controls playback in another application or service, however, running many irrelevant user interfaces to play music results in a lot of memory waste. applications like this can be separated into two processes: one process is responsible for UI work, and the other one is responsible for running other work in the background service.

                Declare the android: process attribute for each component in the manifest file of each application as different processes. for example, you can specify that the service you run is separated from the main process into a new process and the name is "background" (of course, the name can be arbitrary ).



Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.