JVM类加载器详细
JVM图
用new创建的对象在堆
函数中的临时变量在栈区
java中的字符串在字符串常量区
一、类初始化
Java程序初始化顺序:
- 父类的静态代码块
- 子类的静态代码块
- 父类的普通代码块
- 父类的构造方法
- 子类的普通代码块
- 子类的构造方法
二、类加载机制
三、JVM的内存
JAVA的JVM的内存可分为3个区:堆(heap)、栈(stack)和方法区(method)
栈区:
- 1.每个线程包含一个栈区,栈中只保存方法中(不包括对象的成员变量)的基础数据类型和自定义对象的引用(不是对象),对象都存放在堆区中
- 2.每个栈中的数据(原始类型和对象引用)都是私有的,其他栈不能访问。
- 3.栈分为3个部分:基本类型变量区、执行环境上下文、操作指令区(存放操作指令)。
堆区:
- 1.存储的全部是对象实例,每个对象都包含一个与之对应的class的信息(class信息存放在方法区)。
- 2.jvm只有一个堆区(heap)被所有线程共享,堆中不存放基本类型和对象引用,只存放对象本身,几乎所有的对象实例和数组都在堆中分配。
方法区:
- 又叫静态区,跟堆一样,被所有的线程共享。它用于存储已经被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等数据。
四、GC
CMS的GC过程有6个阶段(4个并发,2个暂停其它应用程序)
- 初次标记(STW initial mark)
- 并发标记(Concurrent marking)
- 并发可中断预清理(Concurrent precleaning)
- 最终重新标记(STW remark)
- 并发清理(Concurrent sweeping)
- 并发重置(Concurrent reset)
五、jvm堆
六、GC触发条件
在程序空闲时。
-
程序不可预知的时候/手动调用 System.gc() 。不要手动调用GC,不管是 JVM 自己调用还是手动调用都会使系统陷入短暂的停顿,给垃圾回收让路,手动调用就违背了我们优化 GC 的初衷了
-
堆内存不足时 GC 会被调用。当应用线程在运行,并在运行过程中穿件对象,若这时内存空间不足,JVM就会强制的调用 GC ,一遍回收内存用于新的分配。若GC 一次之后仍不满足内存分配的要求,JVM会再次进行两次 GC 做进一步尝试,若还是不满足需求则会抛出 “out of memort” 的错误使应用异常停止
七、是否符合垃圾收集器收集标准
在java语言中,判断一块内存空间是否符合垃圾收集器收集标准的标准只有两个:
1.给对象赋值为null,以下没有调用过。
2.给对象赋了新的值,重新分配了内存空间。