推荐阅读:

一、阿里逆天级调优方案,内部这套Java性能调优实战宝典,堪称教科书

二、亿万级流量性能瓶颈:JVM底层原理及性能调优实战教程

三、阿里的调优方案,不愧是业界No.1,吹爆这份Java性能调优笔记

一、概念

1、jvm生命周期

启动:当启动一个java程序时,一个jvm实例就诞生了,任何一个拥有main方法的class都可以作为jvm实例运行的起点。

运行:main()函数作为程序初始线程起点,其它线程由该线程启动,包括守护线程(daemon)和non-daemon(普通线程)。守护线程是JVM自己使用的线程比如GC线程就是个守护线程,只要这个jvm实例还有普通线程执行,就不会停止,但是可以用exit()强制终止程序。

消亡:所有非守护线程退出时,JVM实例结束生命,若安全管理器允许,程序也可以使用java.lang.Runtime类或者System.exit(0)来退出。实际上exit也是用到Runtime类来退出,Runtime是个神奇的类,它还可以用于启动和关闭非java进程。

2、JVM与Class文件

我们一直说java虚拟机实现的与语言是无关的,java虚拟机不和包含java在内的任何语言绑定,它只和与class文件这种特殊的二进制文件格式所关联,class文件中包含了java虚拟机指令集符号表以及若干其他辅助信息。基于安全方面的考虑, Java 虑拟机规范要求在 Class 文件中使用许多强制性的语法和结构化约束,但任一门功能性语言都可以表示为一个能被 Java 虚拟机所接受的有效的 Class 文件。作为一个通用的、机器无关的执行平台,任何其他语言的实现者都可以将 Java 虚拟机作为语言的产品交付媒介。例如,使用 Java 编译器可以把 Java 代码编译为存储字节码的 Class 文件,使用 JRuby 等其他语言的编译器同样可以把程序代码编译成 Class 文件,虚拟机并不关心Class 的来源是何种语言,如图。

3、什么是Class文件

Java字节码类文件(.class)是Java编译器编译Java源文件(.java)产生的“目标文件”。它是一种8位字节的二进制流文件, 各个数据项按顺序紧密的从前向后排列, 相邻的项之间没有间隙, 这样可以使得class文件非常紧凑, 体积轻巧, 可以被JVM快速的加载至内存, 并且占据较少的内存空间(方便于网络的传输)。

class文件是一组以8位字节为基础单位的二进制流。

class文件中的信息是一项一项排列的, 每项数据都有它的固定长度, 有的占一个字节, 有的占两个字节, 还有的占四个字节或8个字节, 数据项的不同长度分别用u1, u2, u4, u8表示, 分别表示一种数据项在class文件中占据一个字节, 两个字节, 4个字节和8个字节。

4、什么是魔数

当我们把class文件转成16进制,我们可以看到文件的头四个字节是cafe babe,这个就称为魔数。,它唯一作用就告诉虚拟机当前的文件就是class文件。
使用魔数而不是用扩展名来进行识别主要是基于安全考虑,因为扩展名我们可以随意通过重命名等方式改动。而通过魔数就算你把结尾改成.clss。但它同样还能在JVM运行,因为它的头部还是cafe babe没变。
很多文件存储标准中都用魔数进行身份标识,如图片gif,jpeg都在文件头部中存储着魔数。

5、jvm常量池

我先讲下概念,接下来我会将class文件转为16进制流后,在举例说明。

常量池中每一项常量都是一个表,jdk1.8有14种结构不同的表结构,这14个表有个共同特点,就是表开始的第一位都是一个u1类型的标志位,JVM根据这个标志位[tag]来确定某个常量池项表示什么类型的字面量,比如tag为1就是指CONSTANT_utf8_info

再看常量池类型表

这14种常量项结构还有一个特点是,其中13表占用得字节固定,只有CONSTANT_Utf8_info占用字节不固定,其大小由length决定。为什么呢?因为从常量池存放的内容可知,其存放的是字面量和符号引用,最终这些内容都会是一个字符串,
这些字符串的大小是在编写程序时才确定,比如你定义一个类,类名可以取长取短,所以在没编译前,无法确定大小不固定,编译后,通过utf-8编码,就可以知道其长度。

在看每一项常量表对应的说明:

二、16进制class文件解析

先看java代码

package com.jincou.demo.domain;
public class XiaoXiao {private String father;public String fatherName() {return "小小她爹";}
}

通过命令自动生成class文件(会在同一目录生成)

javac XiaoXiao.java

在将class文件拖入文本编辑器里,显示自然就是16进制流了,如下:

上面的表其实可以划分为以下七个部分,.class 字节码文件包括:

  • 魔数与class文件版本
  • 常量池
  • 访问标志
  • 类索引、父类索引、接口索引
  • 字段表集合
  • 方法表集合
  • 属性表集合

这篇博客只讲到常量池,其它的下篇讲,接下来我们一行一行解释,首先是:

cafe babe:上面说过了这个是魔数,告诉JVM虚拟机我就是class文件。

0000 0034:次版本号组成u2+主版本号u2。共占4个字节。0034转10进制为52,代表当前JDK版本为1.8。

0013 :说明有19-1即18个常量。

上面这些位置是固定的。接下来就是说明每一个常量:

0a:这就是tag代表一个标志,0a代表10,去找常量池列表。

得知它是一个接口中方法的符号引用,然后去找CONSTANT_Methodref_info对应常量列表描述:

从常量列表我们可以知道该类型一共占了5u,即0a00 0400 0f,那么下一个tag就是08代表字符串类型常量,以此类推就可以知道一共18个常量的信息。

三、class反编译

通过上面看16进制的却太麻烦了,现在我们可以通过JDK自带反编译工具查看会更加清晰。

javap -verbose 文件名

通过反编译看去就很直观,比如第一个字符常量很明显告诉你是CONSTANT_Methodref_info,而且对于的就是4和15和上面完美对应。

最后思考,到底哪些会放到常量池?

1.常量池可以理解为class文件中的资源仓库,有很多种类型,主要存放两大常量
①.字面量
字面量就是通俗理解的java常量,如文本字符串,8大基本数据类型,final修饰的常量值等
②.符号引用
符号引用属于编译原理的概念,主要包含以下三种
1)类和接口的全限定名
2)字段的名称和描述符
3)方法的名称和描述符

【JVM虚拟机】(5)---深入理解JVM-Class中常量池相关推荐

  1. java中==与equals的区别及理解_Java开发中常量池的理解与归纳

    相关概念 1.什么是常量 用final修饰的成员变量表示常量,值一旦给定就无法改变! final修饰的变量有三种:静态变量.实例变量和局部变量,分别表示三种类型的常量. 2.Class文件中的常量池 ...

  2. python中常量池和堆_JVM详解之:运行时常量池

    简介 JVM在运行的时候会对class文件进行加载,链接和初始化的过程.class文件中定义的常量池在JVM加载之后会发生什么神奇的变化呢?快来看一看吧. class文件中的常量池 之前我们在讲cla ...

  3. jvm内存参数配置_idea中设置JVM参数,简单理解JVM常见参数,JVM调优简单入门

    前面学习了JVM的内存分布,今天就来验证下.顺便通过测试学习一下JVM的几个参数,不过测试是在idea中,所以先要在idea上设置JVM参数. 一.idea设置全局的JVM参数 一共三步,第一步在菜单 ...

  4. 走进JVM【二】理解JVM内存区域

    引言 对于C++程序员,内存分配与回收的处理一直是令人头疼的问题.Java由于自身的自动内存管理机制,使得管理内存变得非常轻松,不容易出现内存泄漏,溢出的问题. 不容易不代表不会出现问题,一旦内存泄漏 ...

  5. jvm虚拟机-什么是jvm

    最近看了一段时间jdk源码,在看源码的过程中对数据的存储不是很清楚,当时就在想数据到底存在哪里去了?以前只是看博客什么的对jvm有一个大概的了解,但是没有深入研究.经过一段时间的研究<<深 ...

  6. 【JVM】LXF_深入理解JVM专题(1-4)

    文章目录 前言 深入理解JVM虚拟机开篇:JVM介绍与知识脉络梳理 深入理解JVM虚拟机1:JVM内存模型 与 永久代的消失 深入理解JVM虚拟机2:JVM垃圾回收基本原理和算法 1. 各种GC的触发 ...

  7. 【JVM】LXF_深入理解JVM专题(5-)

    文章目录 深入理解JVM虚拟机5:虚拟机字节码执行引擎 一.方法调用的本质 二.运行时栈帧结构 1. 局部变量表 2. 操作数栈 3. 返回地址 4. 方法调用 5. 静态分派 6. 动态分派 7. ...

  8. 聊聊JVM(六)理解JVM的safepoint

    safepoint是JVM里面很重要的一个概念,在很多场景下都会看到它,尤其是在GC的时候.这篇讲讲safepoint.本人不是做JVM实现研究的,很多地方只能点到为止,希望能够讲清楚这个概念,具体的 ...

  9. JVM系列之深入理解JVM(三)

    目录: HotSpot 虚拟机详解: 类加载机制: JMM Java内存模型: Java运行时数据区: 堆的内存划分: JVM优化: GC垃圾回收: 一 HOTSPOT虚拟机详解 1. Java对象创 ...

最新文章

  1. git 下载的文件与git上面的文件不相同的处理方法
  2. sparkcore分区_Spark学习:Spark源码和调优简介 Spark Core (二)
  3. winsock 函数声明大全
  4. Arduino作为服务器显示温度,基于Arduino 带LCD显示的电子温度计
  5. 循环语句练习题2(打印三角形和菱形)
  6. java 类型转换 安全_JAVA 类型转换指令
  7. SpringBoot整合freemarker中自定义标签获取字典表的数据
  8. web开发时浏览器兼容性问题汇总
  9. Mugeda(木疙瘩)H5案例课—教你玩转密室逃脱类H5-岑远科-专题视频课程
  10. 【英语语法入门】第44讲 假设(03)与过去事实相反的虚拟语气
  11. 应用数学是关于计算机,应用数学学科
  12. ProxySQL 配置详解及读写分离(+GTID)等功能说明2 (完整篇)
  13. 第7章第10节:分割式布局:纵向居中分割版面 [PowerPoint精美幻灯片实战教程]
  14. 年轻程序员如何快速成长
  15. 读叔本华之《人生的智慧》
  16. 读《曾国藩》笔记2--慈不掌兵
  17. 【信号与系统】(六)连续系统的时域分析 ——冲激响应与阶跃响应
  18. teamviewer出现无法连接伙伴问题
  19. 利用BARK和Telebot进行VPS实时预警推送
  20. html制作满天星,新鲜满天星如何做干花,满天星干花制作4大方法

热门文章

  1. 计算机技术在建筑的应用浅论,浅析虚拟现实技术在建筑设计领域中的应用
  2. U盘插入有响应但找不到U盘的解决方法
  3. JAVA项目之天天酷跑-Day02
  4. 在Azure 中国区如何备案? 了解前置审批/ICP备/ICP证/公安备案
  5. 2022-2028年中国健身休闲产业深度调研及投资前景预测报告
  6. 使用Feign服务远程调用项目启动时报错:Field xxx in xxx required a bean of type xxx that could not be found.
  7. 关于推迟2021年11月28日PMI认证考试的通知
  8. 转载:Linux下启动和关闭Weblogic(管理服务器+被管服务器)
  9. eclipse查看euc-jp编码格式的文件
  10. PASCAL VOC统计各类目标数量