1、java内存管理中的出现的典型问题:
- 悬挂指针问题:一个指针引用了一个已经被回收的内存地址,导致程序的运行完全不可知。
- 内存泄漏:内存已经分配,但是已经没有了指向该内存的指针,导致内存泄漏。
2、JVM加载class文件的原理机制:
JVM中类的装载时由类加载器和它的子类来实现的,Java中的类加载器是一个重要的Java运行时系统组件,它负责在运行时查找和装入文件中的类。
当java程序需要使用某个类时,JVM会确保这个类已经被加载,连接(验证、准备和解析)和初始化。
类的加载是指把类的.class文件中的数据读入到内存中,通常是创建一个字节数组读入.class文件,然后产生与所加载类对应的Class对象。加载完成后,此时类还不能用。
当类加载后就进入连接阶段,这一句阶段包括验证、准备和解析三个步骤。
最后JVM对类进行初始化,包括:1)如果类存在直接的父类并且这个类还没有被初始化,那么就先初始化父类;2)如果类中存在初始化语句,就依次执行这些初始化语句。
3、JVM原理:
JVM是整个java实现跨平台的最核心的部分,所有的java程序会首先被编译为.class的类文件,这种类文件可以在虚拟机上执行。JVM的主要工作是解释自己的指令集到CPU的指令集或对应的系统调用。JVM对上层的java源文件是不关心的,它关注的只是由源文件生成的类文件(.class文件)
4、内存泄漏与溢出的区别:
- 内存泄漏是指分配出去的内存无法回收了
- 内存溢出是指程序要求的内存,超出了系统所能分配的范围,从而发生溢出
- 内存溢出是提供的内存不够,泄漏是无法在提供内存资源
5、类加载器:
- 启动类加载器
- 扩展类加载器
- 应用程序类加载器
6、双亲委派模型:
当一个类收到了类加载请求,它首先不会尝试自己去加载这个类,而是把这个请求委派给父类去完成,每一个层次类加载器都是如此,因此所有的加载器请求都应该传送到启动类加载器中,只有当 父类加载器反馈自己无法完成这个请求时,子加载器才会尝试自己去加载。
7、垃圾回收算法:
- 标记清除算法:最基础的垃圾回收算法,分为两个阶段,标记和清除。标记阶段标记出所有需要回收的对象,清除阶段回收被标记的对象所占用的空间。该算法最大的问题是内存碎片化严重,后续可能发生大对象不能找到可利用的空间问题
- 复制算法:为了解决标记清除算法内存碎片化的缺陷而被提出的算法。内存容量将内存划分为等大小的两块。每次只使用其中一块,当这一块内存满后将尚存活的对象复制到另一块上去,把已使用的内存清掉。这种算法最大的问题是可用内存被压缩到了原本的一半。且存货对象增多的话,算法效率会大大降低。
- 标记整理算法:标记阶段和Mark-Sweep算法相同,标记后不是清理对象,而是将存活对象移向内存的一端,然后清除边界外的对象。
- 分代收集算法:分代收集算法是目前大部分JVM所采用的方法,其核心思想是根据对象存活的不同生命周期将内存划分为不同的域,一般情况下将GC堆划分为老生代和新生代。老生代的特点是每次垃圾回收时只有少量对象需要被回收,新生代的特点是每次垃圾回收时都有大量垃圾需要被回收,因此可以根据不同区域选择不同的算法。
8、JVM类加载机制:
JVM类加载机制分为五部分:加载、验证、准备、解析、初始化。
- 加载:这个阶段会在内存中生成一个代表这个类的.class对象,作为方法区这个类的各种数据的入口
- 验证:确保class文件的字节流中包含的信息是否符合当前虚拟机的要求
- 准备:在方法区中分配这些变量所使用的内存空间
- 解析:虚拟机将常量池中的符号引用替换为直接引用的过程
- 初始化