An overview of the

First of all, I throw the problem to you, this problem is also my factory students do a performance analysis of the product encountered a problem.

Can the same classloader object load the same Class file multiple times and get multiple Class objects that can all be used by the Java layer

Please pay close attention to the key words in the description above

  • Same classloader: means not a new classloader object every time, which I know some of you who know a little bit about classloaders will think about. We emphasize here that the same classloader object is loaded.

  • Same class file: this means that the information in the class file is the same and cannot be changed, at least the name cannot be changed. Because some students will take advantage of loopholes, such as the class file and change the name, haha.

  • Multiple Class objects: means that each creation is a new Class object, rather than returning the same Class object.

  • Can be used by the Java layer: means that the Java layer can sense, perhaps to my public account for a long time students have seen some of my articles, know what I am talking about here, don’t know can read my previous article, here to keep in mind, not directly tell you which article, a little hint and memory GC.

Well, before you read the following article, I think you can take a vote,

I don’t think 99.99% in the headline is an exaggeration, but I think the percentage should be much higher, but please answer carefully and don’t pick randomly, I know someone will pick randomly, haha.

Normal class loading

I’m talking about normal class loading, which we all understand as a class loading mechanism, but I’ll go a little deeper and talk about it from the perspective of JVM implementation. In the JVM, there is a data structure called SystemDictonary, which is used to retrieve class information. The klass structure is used to retrieve class information. Key is the name of the classloader object + class, and value is the address pointing to Klass. So when one of our classloaders loads a class properly, we look in the SystemDictonary to see if there is one that klass can return, and if there is one, we return it, otherwise we create a new one and put it in a structure that delegates the class loading process I won’t talk about.

It seems unlikely that the same class loader will load the same class more than once.

And that’s true under normal circumstances.

Strange phenomenon

However, we have seen some similar phenomena in the memory structure of Java processes, and here are some screenshots from our performance analysis product

In this phenomenon, the name for the Java lang. Invoke. LambdaForm $BMH class have more than one, and the class loader is BootstrapClassLoader, also is the same class loader to load more than the same class. This is our analysis tool is there a problem? Obviously not, because that’s what we read in memory.

The phenomenon of simulated

The above phenomenon seems to have something to do with lambda, but it’s not just lambda. We can simulate it

public static void main(String args[]) throws Throwable { Field f = Unsafe.class.getDeclaredField("theUnsafe"); f.setAccessible(true); Unsafe unsafe = (Unsafe) f.get(null); String filePath = "/Users/nijiaben/AA.class"; byte[] buffer =getFileContent(filePath); Class<? > c1 = unsafe.defineAnonymousClass(UnsafeTest.class, buffer, null); Class<? > c2 = unsafe.defineAnonymousClass(UnsafeTest.class, buffer, null); System.out.println(c1 == c2); }Copy the code

The Unsafe object’s defineAnonymousClass method is used to load the same Class file twice to get two Class objects, which we’ll print false. This means that C1 and C2 are really two different objects.

Because our class files are all the same, and the class names in the bytecode are exactly the same, the names of class objects in the JVM are actually the same. The hash value is the hashCode value of the corresponding Class object. The hash value is the hashCode value of the corresponding Class object. This is actually a special processing in the JVM.

In addition, you can’t get this Class through other Java apis like class.forname, so you need to save the resulting Class object before you can use it later.

The explanation of defineAnonymousClass

DefineAnonymousClass is an unusual method that, as the name suggests, creates an anonymous class, but the concept of anonymity is not quite the same as what we think of as anonymity. This class to create classes often have a host, which is the first parameter specifies the class, as a result, the creation of the definition of a class will use the host class class loader to load this class, the key point is the class is created after SystemDictonary will not be lost to the above, that is to say we through normal class lookup, Apis such as class.forname have no way of checking whether a Class has been defined. So overusing the API to create such classes is a bit of a memory leak.

Then one has to ask, see what benefits, why to provide this API, what is the point of doing so, you can check out JSR292. The JVM supports dynamically typed languages through InvokeDynamic, so we can actually provide a class template that dynamically replaces some of the constant pool when loading a class at run time, so that we can load the same class file multiple times and pass in different cpPatches. This is the third parameter to defineAnonymousClass, which makes a difference at run time.

This is mainly because the original JVM class loading mechanism did not allow this to happen, because we can only load a class with the same name by the same classloader once, so in order to support the dynamic language features, provide a similar API to achieve this effect.

conclusion

In general, the same class file can only be loaded once by the same class loader object. However, using the Unsafe defineAnonymousClass, you can ensure that the same class file can be loaded multiple times by the same class loader object. Since we didn’t put it in the SystemDictonary, we can load the same class an infinite number of times. This is for the vast majority of people don’t understand, so everyone at the time of the interview, you can clear the situation in this article, I believe that is a plus, but may also be injured, because your interviewer may also not clear this kind of situation, but you can tell him my this article, ha ha, please help a good harvest, and share out, thank you.

PS: Some time ago, Tencent Cloud unwittingly recovered JVMPocket’s server, resulting in the unavailability of JVMPocket. If you need JVM parameters, you can visit our more powerful XXFox product to use it for free. The address is xxfox.perfma.com. In fact, is a free JVM products with feelings, recommended to everyone

Recently, due to the economic recession, major companies are downsizing, but our company PerfMa still needs some technical talents to join us. If you have a special pursuit of technology and like to make continuous breakthroughs in the underlying technology, please feel free to contact me (wechat: Han_ quanzi), if you have read this article harvest, I believe that there will be more harvest after coming. If you have experience in performance analysis, performance profiling, link tracking, etc. Of course, if your company has these requirements of customers can also contact me, ha ha.

I have other JVM related articles

  • PerfMa in winter: We want to be a facilitator of enterprise technical services

  • Fake stupid. – A case where the process disappears

  • JDK12 has officially included our Patch

  • False false – helped meituan kafka team locate a JVM Crash problem

  • There is a BUG in upgrading to JDK9, do you know about it

  • It, in fact, is a free sentient JVM product, recommended to everyone

  • Fake stupid q&A – a small but rewarding example of JVM memory

  • Stupid. – Can we talk more about memory overflow?

  • Identify a JVM design flaw that causes GC to slowly grow

  • False nonsense – Beware of the creation of a large number of class loaders resulting in a weird Full GC

  • – Check JVM parameters for JVMPocket(JVM pocket) applets

  • Nonsense – I have something to say about the problem of frequent GC due to dynamic array expansion

  • Another ghost that causes frequent GC – array dynamic expansion

  • False stupid – class initialization deadlock causes thread to explode! Blow! Blast!

  • Beware of memory leaks caused by duplicate class definitions in JDK8

  • Fake stupid. – From a GC murder to the principle of reflex

  • How did I get into the JVM

  • False stupid – digging into the JVM’s displacement operations from X86 instructions

  • The JVM source code analyzes how many threads a Java process can create

  • JVM source code analysis of String. Intern () causing YGC to get longer

  • Class. GetMethods for JVM source code analysis without guarantee of order

  • Metaspace decryption for JVM source code analysis

  • JVM source code analysis of the critical foot of OutOfMemoryError full interpretation

  • JVM source code analysis of uncontrolled out-of-heap memory

  • Full interpretation of jSTAT tool principle for JVM source analysis

  • JVM source code analysis of zombie classloaders in JDK8

  • JVM source code analysis stack overflow full interpretation

  • The Attach mechanism for JVM source analysis implements full interpretation

  • How does a custom class loader for JVM source analysis elongate YGC

  • Complete interpretation of JVM source code analysis FinalReference

  • JVM source code analysis of the JavaAgent principle of full interpretation

  • JVM source code analysis Object. Wait /notify(All

  • JVM source code analysis out of the heap memory full interpretation

  • JVM source code analysis SystemGC complete interpretation

  • Changes in generic type derivation in JDK8

  • Cenozoic Enlargement before and after YGC?

  • Deadlocks disappear

  • Process physical memory is much larger than Xmx problem analysis

  • An irreversible class initialization process

  • JDK SQL design is not properly caused by the driver class initialization deadlock problem

  • How do I locate the threads that consume the most CPU

  • Why did Java start on January 1, 1970

Welcome to follow your personal wechat public account, mainly around the JVM to write a series of fundamental, performance tuning articles, you can also follow our company’s public account