JVM原理 GC工作机制详解 Java Virtual Machine 一、JVM结构1.GC是负责回收所有无任何引用对象的内存空间。注意垃圾回收回收的是无任何引用的对象占用的内存空间而不是对象本身2.GC回收机制的两种算法a.引用技术法b.可达性分析算法1类加载器classloader在JVM启动时或者在类运行时将需要的class加载到JVM中。为什么要知道类加载机制按需加载JVM启动时不能确定我们需要加载哪些东西或者有些类非常大我只希望用到它的时候加载并非一次性加载所有的class所以这个时候要了解加载机制就可以按需加载了类隔离在部署多个应用应用之间互相可能会有冲突希望尽量隔离这里可能就要分析应用加载的资源和加载顺序之间的冲突针对这些冲突自己定义规则资源回收如果你不了解java如何加载资源的需要理解Java的加载机制一般说到java的类加载机制都要提到“双亲委派模型”这种机制可以避免重复加载当父类已经加载了该类的时候就没有比较子classloader再加载一次JVM会根据类名包名classloader实例ID来判断两个类是否相同是否加载过。类加载顺序bootsrapclassloader -----extensionclassloader----appclassloader----customclassloader检查类是否已经加载方向和类加载顺序相反bootstrapclassloader:他时最顶级的类加载器是由C编写而成已经内嵌到JVM中了在JVM启动的时候会初始化该classloader它主要作用时来读取java的核心类库JRE/lib/rt.jar中的所有class文件这个jar中包含了java规范定义的所有接口和实现。extensionclassloader:他时用来读取java的一些扩展类库如读取JRE/lib/ext/*.jarappclassloader:他是用来读取classpath下指定的所有jar包或目录的类文件一般情况下这就是程序默认的类加载器customclassloder:他是用户自定义编写的它用来读取指定类文件。基于自定义的classloader用户加载非classpath中的jar和目录如网络下载下载的jar或则二进制文件还可以加载之前class文件优化一些动作如解密编码等2执行引擎负责执行class文件中包含的字节码指令3内存区运行时数据区在JVM运行时候操作所分配的内存。运行时内存主要可以划分5个区域方法区用于存储类结构信息的地方包括常量池静态变量构造函数等运行时常量池java堆heap:存储java实例或者对象的地方这一块是GC的主要区域这个堆是所有java线程共享的java栈stack:栈总是和线程关联在一起每当创建一个线程时JVM就会为这个线程创建一个对应的java栈在这个java栈中又会包含多个栈帧每运行一个方法就 创建一个栈帧用户存储局部变量操作栈方法返回值每个方法从调用直至完成的过程就对应着一个栈帧在java的入栈到出栈的过程栈线程私有的。程序计数器PC register:用于保存当前线程执行的内存地址由于JVM程序时多线程执行的线程轮流切换所以为了保证线程切换回来后还能恢复到原先状 态就需要一个独立的计数器记录之前中断的地方可见程序计数器也是线程私有的。本地方法栈和java栈的作用差不多不过时为了JVM使用到的native方法服务的。4本地方法接口主要时调用C或C实现的本地方法以及返回结果。二、内存分配java内存申请静态内存和动态内存java栈、程序计数器、本地方法栈都是线程私有的线程在就在销毁就消失。内存也跟着回收这个几个区域内存分配和回收时确定的但是java堆和方法区不一样我们只能在程序运行期间才知道会创建哪些对象所以这部分内存分配和回收时动态的。一般来说垃圾回收时针对的这一部分。三、垃圾检测、回收算法垃圾收集器检测垃圾回收垃圾检测垃圾引用技术法给一个对象添加引用计数器每当有个地方引用它计数器就加一引用失效计数器就 减一。A对象引用B ,B对象引用A 会有问题可达性分析法解决上面相互引用的问题 GC Roots 扫描垃圾回收算法标记-清除法复制标记-整理标记-清除和复制算法优点结合分代收集算法类的生命周期加载 连接 初始化 使用 卸载四、Java中堆和栈的区别栈:(1)线程私有的内存区域。(2)每个线程在创建的时候都会分配一个独立的栈(3)主要用于存储方法执行时候的栈帧帧弹出销毁不涉及垃圾回收栈自己管理(4)天然线程安全私有(5)无碎片化的内存问题(6)后进先出堆:(1)线程共享的内存区域.(2)JVM启动时创建整个JVM只有一个堆。(3)主要用于存储对象实例和数组new 创建的对象(4)垃圾回收的主要区域五、JVM为什么使用元空间替换永久代对比维度永久代元空间内存区域JVM堆内存的一部分本地内存大小限制固定范围大小64M-1GB需要手动配置动态扩展默认无上限物理内存限制内存溢出风险高容易因为类多触发OOM低垃圾回收与老年代绑定回收效率低独立回收针对无用的类跨虚拟机兼容性仅支持HotSpot支持所有JVM实现统一支持