有关java虚拟机(JVM)的一些知识点及GC相关的一些知识点小结。
最后附带脑图==========最后边
JVM结构
- JAVA堆
唯一目的就是存放对象,一个JVM实例只存在一个堆,堆内存的大小是可以调节的。堆内存是线程共享的。 - 方法区
各个线程共享的内存区域,它用于存储已被虚拟机加载的类信息、常量、静态变量等数据。 - JAVA栈
每个方法被执行的时候都会同时创建一个栈帧(Stack Frame )用于存储局部变量表、
操作栈、动态链接、方法出口等信息。线程私有(线程隔离) - 本地方法栈
为虚拟机使用到Native 方法服务。 - 程序计数器
当前线程所执行的字节码的行号指示器
每个线程都有自己的程序计数器即线程之间隔离
JVM Memory
部分空间依赖用户线程的启动/停止而创建/销毁(栈)
GC
显示内存管理(C/C++)
由程序员进行内存的申请和释放
内存泄露:内存空间已经申请,使用完毕后未主动释放
野指针:使用了一个指针,但是该指针指向的内存空间已经被free
隐式内存管理(Java/C#)
内存的管理是由垃圾回收器自动管理
优点:增加了程序的可靠性,减小了memory leak
缺点:无法控制GC的时间,耗费系统性能
“垃圾”的确认
引用计数法
根搜索算法
可达对象 有用对象
不可达对象 垃圾对象
“垃圾”的回收
- 标记清除算法(Mark Sweep)
优点:简单、效率高
缺点:容易产生内存碎片 - 标记复制算法(Copy)
优点:存活对象很少的时候,只需要复制少量对象,而且回收整片内存区域;效率也高没有内存碎片
缺点:存活对象多的时候,需要复制大量对象,内存回收率不是很高;内存利用率:50% - 标记整理算法(Mark Compact)
优点:标记/整理算法不仅可以弥补标记/清除算法当中内存区域分散的缺点,也消除了复制算法当中,内- 存减半的高额代价
缺点:标记/整理算法唯一的缺点就是效率也不高,不仅要标记所有存活对象,还要整理所有存活对象的引用地址,再进行存活对象的移动。从效率上来说,标记/整理算法要低于复制算法 - 分代收集算法(Generational Collection 商用)
结合新生代和老年代的特点使用合适的算法进行收集
GC相关概念
Shallow size
就是对象本身占用的内存大小,也就是对象头加成员变量占用内存大小的总和
Retained size
是该对象自己的shallow size 加上仅可以从该对象访问(直接或者间接访问)的对象的shallow size之和
GC触发时间
1、申请heap space失败后会触发GC回收
2、系统进入idle(空闲状态)后一段时间会进行回收
3、主动调用GC进行回收
内存相关问题
堆溢出:Heap OOM=>Out Of Memory
栈溢出:Stack Overflow
内存泄露
是指程序中己动态分配的堆内存由于某种原因程序未释放或无法释放,造成系统内存的浪费,
导致程序运行速度减慢甚至系统崩溃等严重后果
内存泄露与内存溢出有联系吗?
内存泄露可能导致内存溢出,但不是必然导致内存溢出