深入JVM
深入理解Java虚拟机内幕。
wind瑞
微信搜索JavaQ,专注Java基础原理分析、微服务实战、分布式系统构建,诚邀关注!
展开
-
Java类的生命周期包括哪几个阶段?
一个Java类被加载到虚拟机中,它的生命周期才算开始,直到被从内存中卸载,它的生命周期才算结束。从开始到结束,它的整个生命周期包括加载、验证、准备、解析、初始化、使用和卸载7个阶段,其中验证、准备和解析3个阶段又被统称为连接。加载加载阶段主要完成以下三件事: 1.通过一个类的全限定名来获取此类的二进制字节流; 2.将这个二进制字节流所代表的静态存储结构转为方法区的运行时数据结构; ...原创 2018-02-12 21:08:01 · 4466 阅读 · 0 评论 -
Class文件中为什么要使用魔数?
Class文件是一组以8位字节为基础单位的二进制流,文件中记录了一个类或接口的定义信息,文件中的各个数据项严格按照顺序紧凑排列,中间不使用分隔符,所以Class文件中存储的都是程序运行必要的参数。每个Class文件的头四个字节被称为魔数,使用十六进制的0xCAFEBABE表示,它的作用是确定这个文件是否为一个能被虚拟机接受的Class文件,起到身份识别的作用。 ...原创 2018-02-12 21:09:49 · 874 阅读 · 0 评论 -
JDK自带的命令行工具有哪些?
在JDK的bin目录下包含了很多功能强大的命令行工具,它们的主要功能代码都是在jdk/lib/tools.jar中实现的。下面一一介绍这些命令行工具。jpsjps是JVM Process Status Tool的简称,用于显示指定系统内所有的HotSpot虚拟机进程。常用的命令有:jps -l //用于输出主类的全名,如果运行的是jar包,则输出jar路径;jps -v //用...原创 2018-02-12 21:11:55 · 3272 阅读 · 0 评论 -
虚拟机如何给对象分配内存?
当创建一个对象时,需要给新生对象分配内存,而分配内存就是在堆上进行分配。在堆上进行分配的时候,可能在新生代的Eden区上,也可能在老年代中分配,具体的分配策略需要参考一些内存分配的规则。优先在Eden区分配大多数情况下,新生对象都在新生代的Eden区进行内存分配,当新生代Eden区没足够空间的时候,会触发一次Minor GC。大对象直接进入老年代当一个新生对象需要大量连续空...原创 2018-02-12 21:13:41 · 2241 阅读 · 0 评论 -
Java虚拟机的垃圾收集器有哪些?
Serial收集器Serial收集器是新生代的垃圾收集器,是一个单线程的收集器,它开始工作时会暂停掉其它所有的工作线程,一直到它工作结束。它是虚拟机运行在Client模式下的默认新生代垃圾收集器,采用复制算法。ParNew收集器ParNew收集器是新生代的垃圾收集器,采用多线程进行垃圾收集和回收,采用复制算法的收集器,它是Serial收集器的多线程版本,它的实现复用了很多Seria...原创 2018-02-08 21:17:50 · 522 阅读 · 0 评论 -
Minor GC、Major GC和Full GC之间的区别?
Minor GCMinor GC指新生代GC,即发生在新生代(包括Eden区和Survivor区)的垃圾回收操作,当新生代无法为新生对象分配内存空间的时候,会触发Minor GC。因为新生代中大多数对象的生命周期都很短,所以发生Minor GC的频率很高,虽然它会触发stop-the-world,但是它的回收速度很快。Major GCMajor GC清理Tenured区,用于回收老...原创 2018-02-08 21:16:20 · 2715 阅读 · 1 评论 -
如何通过引用定位堆中对象的具体位置?
当一个对象被创建后,要想使用它,可以通过Java虚拟机栈上的引用数据来操作堆上的具体对象,引用如何定位堆中对象的具体位置,不同的虚拟机实现不同,常用的定位方式有句柄和直接指针两种。句柄方式句柄方式需要在堆中划分出一块区域用作句柄池,引用中存储的是对象的句柄地址,而句柄中存储了对象实例数据地址和类型数据地址。简单说就是,引用中存储的是对象的句柄地址,而这些句柄存储在堆中的句柄池中,而池中...原创 2018-02-08 21:12:31 · 1487 阅读 · 0 评论 -
如何确定JVM堆中哪些对象是可以被回收的
垃圾回收器在对堆进行回收之前,需要确定堆中哪些对象是可以继续存活的,哪些是可以被回收的,Java采用可达性分析算法来判定对象是否可以继续存活。这个算法的过程是通过一系列的称为“GC Roots”的对象作为起点,从这些起始点开始向下搜索,搜索过程中所有走过的路径称为引用链,当一个对象和引用链没任何连接的时候,则表明这个对象是可以被回收的。可作为“GC Roots”对象的有如下几种:Jav原创 2018-01-30 22:05:00 · 1269 阅读 · 1 评论 -
如何通过代码查看JVM堆和非堆的使用情况
MemoryMXBean memoryMXBean = ManagementFactory.getMemoryMXBean();System.out.println(memoryMXBean.getHeapMemoryUsage());System.out.println(memoryMXBean.getNonHeapMemoryUsage());原创 2018-02-04 12:19:55 · 2517 阅读 · 0 评论 -
JVM的方法区可以实现垃圾回收吗?
方法区和堆一样,都是线程共享的内存区域,被用于存储已被虚拟机加载的类信息、即时编译后的代码、静态变量和常量等数据。根据Java虚拟机规范的规定,方法区无法满足内存分配需求时,也会抛出OutOfMemoryError异常,虽然规范规定虚拟机可以不实现垃圾收集,因为和堆的垃圾回收效率相比,方法区的回收效率实在太低,但是此部分内存区域也是可以被回收的。方法区的垃圾回收主要有两种,分别是对废弃常量原创 2018-02-04 12:21:29 · 2743 阅读 · 0 评论 -
JVM垃圾回收算法有哪几些?
常用的垃圾回收算法有如下四种:标记-清除、复制、标记-整理和分代收集。标记-清除算法 从算法的名称上可以看出,这个算法分为两部分,标记和清除。首先标记出所有需要被回收的对象,然后在标记完成后统一回收掉所有被标记的对象。这个算法简单,但是有两个缺点:一是标记和清除的效率不是很高;二是标记和清除后会产生很多的内存碎片,导致可用的内存空间不连续,当分配大对象的时候,没有足够的空间时不得不提前触原创 2018-02-04 12:22:40 · 2754 阅读 · 0 评论 -
Java虚拟机为新生对象分配内存有哪两种方式?
当使用new关键字创建一个类的对象时,虚拟机需要为新生对象分配内存空间,而对象的大小在类加载完成后已经确定了,所以分配内存只需要在Java堆中划分出一块大小相等的内存。在Java虚拟机中有指针碰撞和空闲列表两种方式分配内存。指针碰撞方式如果Java堆中内存是规整排列的,所有被用过的内存放一边,空闲的可用内存放一边,中间放置一个指针作为它们的分界点,在需要为新生对象分配内存的时候,只要将原创 2018-02-04 12:24:08 · 896 阅读 · 1 评论