为什么我们要了解JVM
私有线程区域:
- 栈:函数当前运行过程中的一些函数变量。存对象的引用类型和地址
- 本地方法栈:存放C++运行时的native栈。
- 程序计数器:指向当前程序运行的位置。
线程共享区域:
- 堆:存对象(最终),老年代。
- 方法区:存储元数据信息,在JDK1.7前作永久代,1.8以后改为元数据空间,存储静态变量和常量、类加载器。
Java的基础数据和指针都是值类型,所以直接存到内存里面去,不是去存地址寻址。
GC
- GC Root本地方法栈,方法区,栈不能被删除
删除方法
- 标记清理,==会产生内存碎片==。
- 标记整理(删了后面的顶上来,减少内存碎片),==前移空间移动代价太大==。
- 复制算法(分为两个区),不直接删除,不被删除的复制到新区,==需要2倍的内存==。
实际:
Minor GC当在 Eden 区分配内存不足时,则会发生 minorGC ,由于 Java 对象多数是朝生夕灭的特性,所以 minorGC通常会比较频繁,效率也比较高。
- 年轻代:E区(伊甸园,满了触发YoungGC,用复制算法),,两个Survive区(S0.S1) 8:1:1,两个S区交替工作(E+S1到S0,E+S0到S1)。每次Young GC完年龄会加一,满15岁就直接都去老年代区了。ParNew垃圾收集器(复制)。
Full GC
- 老年代:只有一块,存满15岁到去老年代区的对象。和大对象,Old满了就和年轻的一起Full GC,发生STOPPED WORLD,整个Java程序直接暂停,就用标记清理或者标记整理。CMS垃圾收集器(标记清理)。
和GC Root无关的才能被删除