JVM内存管理 当JVM运行一个Java程序的时候,必须先由类加载器把相关的Java类载入内存。另外,JVM需要存储一些信息,包括类的字节码、从类文件中提取出来的一些附加信息、程序中实例化的对象、方法参数和返回值、局部变量以及计算的中间结果等。
JVM的内部体系结构。如下图所示
栈内存(Stack):基本数据类型变量直接在栈内存中保存值,引用类型变量在栈内存中只保存指向堆内存的对象的地址(即指针)。栈内存空间采用FILO(FirstInLastOut)内存管理机制,存取速度快、效率高。
堆内存(Heap): 堆内存用来存放对象的内容。堆内存因运行时动态分配内存和回收内存,导致效率较低,比较耗费内存。
ClassLoader基本概念
Java程序并不是一个可执行文件,而是由许多独立的类文件组成,每一个文件对应一个java类。这些类文件并非全部装入内存,而是根据程序需要逐渐载入。
ClassLoader是JVM实现的一部分,ClassLoader包括bootstrap classloader(启动器加载类)。
用户定义的ClassLoader通过java程序实现的两个ClassLoader:一个是ExtClassLoader,另一个是AppClassLoader。
ExtClassLoader:作用是用来加载Java的扩展API也就是/lib/ext中的类。
AppClassLoader:用来加载用户机器上CLASSPATH设置目录中的class的通常在没有指定ClassLoader的情况下,程序员自定义的类就由该ClassLoader进行加载。
类加载器:通过一个类的全限定名来获取描述此类的二进制字节流,实现这个动作的代码模块称为“类加载器”。
ClassLoader加载流程
当运行一个程序的时候,JVM启动,运行bootstrap classloader,该ClassLoader加载Java核心API(ExtClassLoader和AppClassLoader也在此时被加载),然后调用ExtClassLoader加载扩展API,最后AppClassLoader加载CLASSPATH目录下定义的Class,这就是一个程序最基本的加载流程。
Class.forName 不仅表示类的类类型,还代表了动态加载类。编译时加载是静态加载类,
运行时加载是动态加载类。
一些重要的方法
- loadClass方法。
- defineClass方法。
- findSystemClass方法。
- resolveClass方法。
- findLoadedClass方法。
- findClass方法。
- getSystemClassLoader方法。
- forName方法。
面试例题
- 下面给出的Java中ClassLoader中的描述,哪些描述是正确的?( C)
A. ClassLoader没有层次关系
B. 所有类中的ClassLoader都是AppClassLoader
C. 通过Class.forName(String className),能够动态加载一个类
D. 不同的ClassLoader加载同一个Class文件,所得的类是相同的