Do you know the size of the data? - Don't spend too much effort to hide class members (3)

zhaozj2021-02-16  43

What can we do?

"This is very good, but we don't have any options that use String and other Java, is this?" I heard you asking, let us find a answer.

l package class

Packages such as java.lang.integer, look that a large amount of data is like a bad choice in memory. If you try our best for the economy, you should avoid this. It is not difficult to use the vector class of your own Int. Of course, if the core function library of Java already contains this, it is best. Perhaps this situation will greatly change when Java has special types.

l Multi-digit array

For large data structures that use multi-dimensional array, you can reduce additional dimensions /, for example: Convert INT [DIM1] [DIM2] instance to an instance of INT [DIM1 * DIM2], change all The expression of A [I] [J] is A [i * DIM1 J]. This way you don't have to spend the index check of Kung Fu on DIM1 to improve efficiency.

l java.lang.string

You can use some tips to reduce the static memory size of strings in your application.

First, you can try a very common technology, just when an application loads or caches a lot of strings from a data file or network connection, and the value of this string is limited. For example: If you want to analyze an XML file, in this file, you often encounter some properties, but this property is only limited to two possible values. Your goal: Filter all strings through a hash map, reducing all the same but obvious strings, and target object references.

Public String Internstring (String S)

{

IF (s == null) Return NULL;

String is = (string) m_strings.get (s);

IF (is! = null)

Return IS;

Else

{

m_strings.put (s, s);

Return S;

}

}

PRIVATE MAP M_STRINGS = new hashmap ();

If applicable, this technique can be doubled to reduce your static memory needs. A rich reader should be able to observe the functionality of this technique to copy java.lang.String.Intern (). There are countless reasons exist to let you avoid using the string.intern () method. One of them is that the current JVM has almost no reservations that can achieve a lot of data.

What happens if your string is completely different? This is the second trick to introduce, re-collected those small string spaces, these spatial potential hidden in the char array because the use array only accounts for half of the memory occupied by the string package. Therefore, when our application caches many unique characters, we only need to be converted to a string as needed. If this string is just a temporary, it will be abandoned soon, which will be effective. A simple experiment is to select 90,000 words as a cache from a dictionary file. These data is about 5.6m size. If it is char, only 3.4m space is required, only 65% ​​of previous 65%.

The second technique is clearly included in a disadvantage, that is, you can't support a string through a constructor, because this constructor does not copy this array and will have this array. why? Because this complete PUBLIC string API ensures that each string is not variable, the constructor of each string obviously wants to copy the input data and then incoming the parameters.

Then we will use the third tip. This trick is used when converting a char array for a string. This skill uses java.lang.string.substr () to avoid data replication: This method is to display the invariance of the string, and a shadow string object created to share character content, but its internal start The position and end position are correct. We still write an example, new string ("smiles"). Substring (1, 5) is a string, which is the character buffer from the character buffer, and the character buffer will share the original characters. Character buffering of string constructor points. You can use this way: give a large string collection, you can merge its character content to a large-character array, create a string on it, and use this primary string to recreate A original string. As described below: public static string [] CompactStrings (String [] strings

{

String [] result = new string [strings.length];

INT OFFSET = 0;

For (int i = 0; i

OFFSET = strings [i] .length ();

// can't Use StringBuffer Due to HOW IT MANAGES CAPACITY

CHAR [] allchars = new char [offset];

OFFSET = 0;

For (int i = 0; i

{

Strings [I] .getchars (0, Strings [i] .length (), allchars, offset;

OFFSET = strings [i] .length ();

}

String allstrings = new string (allchars);

OFFSET = 0;

For (int i = 0; i

Result [i] = allstrings.substring (offset,

Offset = strings [i] .length ());

Return Result;

}

The above method returns a new string set equivalent to the input character set, but is more compact in memory. Re-obtain 16 bytes of heads of each string array, which is effectively removed in the method. This storage is more effective when the buffer compression is short. When this method is used for the same 90,000 word dictionary, memory is mainly covered from 5.6m to 4.2m, which is about 30%.

l Is these efforts worth it?

The way I mentioned here seems to be very subtle optimization, is it worth spending time to achieve? However, remember that our brain should remember that the server's application can cache a large amount of data in memory, which can greatly improve the performance and efficiency of data from the disk and database. In the current 32-bit JVM, a few hundred trillor cache data represents a position in the stack. Reducing 30% or more should not be launched, it can improve the performance of the system's measurable nature. Of course, these techniques do not apply to data structures that are well designed at the beginning, and the facts decisions should be determined by Hotspots. Anyway, you should now know how much memory your object consumes.

About the Author:

转载请注明原文地址:https://www.9cbs.com/read-26505.html

New Post(0)