类的加载机制
加载->验证->准备->解析->初始化->使用->卸载,7个阶段。其中验证、准备、解析3个部分统称为连接。
加载
- 通过一个类的全限定名来获取类的二进制字节流。
- 将这个字节流所代表的静态储存结构转化为方法区的运行时数据结构。
- 内存中生成java.lang.Class对象(HotSpot中存于方法区),作为方法区这个类的各种数据的访问入口。
验证
这一阶段的目的是为了确保Class文件的字节流中包含的信息符合当前虚拟机的要求,并且不会危害虚拟机自身的安全
准备
为类的静态变量分配内存,并将其初始化为默认值。基本数据类型初始值为0,引用数据类型初始值为null
解析
将类的二进制数据中的符号引用全部替换为直接引用。
初始化
为类的静态变量赋予正确的初始值,JVM负责对类进行初始化,主要对类变量进行初始化
- 声明类变量是指定初始值
- 使用静态代码块为类变量指定初始值
GC(垃圾回收)
回收算法
标记清除算法
标记-清除算法(Mark-Sweep)是一种常见的基础垃圾收集算法,它将垃圾收集分为两个阶段:1.标记阶段 2.清除阶段
效率低、回收的频率高
复制算法
它把内存空间划为两个相等的区域,每次只使用其中一个区域。垃圾收集时,遍历当前使用的区域,把存活对象复制到另外一个区域中,最后将当前使用的区域的可回收的对象进行回收
运行高效但可用的内存大小缩小了一半
标记整理算法
标记可回收的对象后将所有存活的对象压缩到内存的一端,使他们紧凑的排列在一起,然后对端边界以外的内存进行回收。回收后,已用和未用的内存都各自一边
比标记-清除算法运行效率高
分代收集算法
根据对象的存活周期将内存划分为:年轻代、老年代 和 永久代
- 新生代(Young generation)
- 新生代中存在一个Eden区和两个Survivor区。新对象会首先分配在Eden中(如果新对象过大,会直接分配在老年代中)。在GC中,Eden中的对象会被移动到Survivor中,直至对象满足一定的年纪(定义为熬过GC的次数),会被移动到老年代
- 老年代(Old generation)
- 占用的空间要比新生代多,正由于其相对较大的空间,发生在老年代上的GC要比新生代要少得多。对象从老年代中消失的过程,可以称之为major GC(或者full GC)。
- 永久代(permanent generation)
- 几乎都是静态的并且很少被卸载和回收
垃圾回收器
垃圾收集器就是内存回收的具体实现
- 新生代回收器:Serial、ParNew、Parallel Scavenge
- 老年代回收器:Serial Old、Parallel Old、CMS
- 整堆回收器:G1
###单线程垃圾回收器
单CPU的环境下,它的垃圾清除效率比较高。
- Serial
Serial 回收器是最基本的新生代垃圾回收器。采用的是->复制算法
- Serial Old
Serial Old 回收器是Serial回收器的老生代版本。采用的是->标记整理算法
多线程垃圾回收器
- ParNew
属于 Serial 回收器的多线程版本,同样运行在新生代区域。在不同运行环境下,根据CPU核数,开启不同的线程数。采用的是->复制算法
- Parallel Scavenge
Parallel Scavenge 回收器也是运行在新生代区域,属于多线程的回收器。ParNew 回收器是通过控制垃圾回收的线程数来进行参数调整,更关心的是程序运行的吞吐量。采用的是->复制算法
- Parallel Old
Parallel Scavenge 回收器的老生代版本,属于多线程回收器。考虑了 吞吐量优先 这一指标,非常适合那些 注重吞吐量 和 CPU 资源敏感 的场合。采用的是->标记整理算法
线程查看辅助工具
jstack
jstack是java虚拟机自带的一种堆栈跟踪工具。jstack用于打印出给定的java进程ID或core file或远程调试服务的Java堆栈信息,如果是在64位机器上,需要指定选项”-J-d64”,Windows的jstack使用方式只支持以下的这种方式:
jstack -l pid
线程状态
- NEW
线程刚刚被创建,但是还没有调用start()方法,jstack命令不会列出处于此状态的线程信息
- RUNNABLE
线程是可运行的
- BLOCKED
线程处于阻塞状态
- WAITING
线程处于等待状态
- TIMED_WAITING
线程等待指定的时间
- TERMINATED
线程终止
jmap
查看Java 堆(heap)使用情况
1
jmap -heap pid
将内存使用的详细情况输出到文件
1
jmap - dump pid
jconsole
Jconsole (Java Monitoring and Management Console),一种基于JMX的可视化监视、管理工具
- 点击JDK/bin 目录下面的jconsole.exe 即可启动
- 然后会自动自动搜索本机运行的所有虚拟机进程。
- 选择其中一个进程可开始进行监控