1-JVM基础
1-JVM基础
java源码文件,通过javac 转换成class文件。
找到.java文件
词法分析器
tokens流
语法分析器
语义分析器
字节码生成器
转成.class文件
装载
根据全限定路径名寻找class文件,转换成二进制流。通过ClassLoder.load(String name)(类装载器,name:全限定路径名)不同路径下的类,设置不同路径的类装载器。
Bootstrap ClassLoader(根装载器由C语言编写):加载
$JAVA_HOME
中的jar/lib/rt.jar
里所有的class或Xbootclassoath
选项指定的jar包Extension ClassLoader:加载Java平台中扩展功能的一些jar包,包括
$JAVA_HOME
中jar/lib/*.jar
或-Djava.ext.dirs
指定目录下的jar
包App ClassLoader:加载classpath中指定的jar包及
Djava.class.path
所指定目录下的类和jar
包Custom ClassLoader(自定义装载器改变装载原则,如Tomcat打破双亲委派机制):通过
java.lang.ClassLoader
的子类自定义加载class,属于应用程序根据自身需要自定义的ClassLoader
,如Tomcat
、JBoss
都会根据j2ee规范自行实现ClassLoader
需要把类文件静态存储结构里面对应的内容存储到JVM里面(方法区的运行时数据结构)
代码里一段方法不宜过长(阿里规范中提到一段方法不应超过80行)。方法存到JVM里的栈帧。内容一旦超过一定行数或者过长时,JVM就会从编译性改变为解释性,从而导致性能下降。
java.lang.Class对象存储到堆内存
链接
验证
保证被加载的正确性。验证class文件中的cafe babe。注:class文件中,已cafe babe为开头的是java文件。
准备
为类的静态变量分配内存。如:
private static int a = 3;//为a分配内存,并且将a初始化默认值,默认值:a=0
解析
将类中的符号引用转换为直接引用。静态的转换。
符号引用:就是class文件中的内容,符合JVM规范的内容,JVM认识的语言。
直接引用:在Java进程中能够代表真实含义的。JVM更底层,计算机能够认识的语言,并且操作的。比方说为某个静态变量分配了真实的内存。
初始化
对类的静态变量,进行正真的初始化。就是将上一步中的准备过程中的
private static int a = 3;//为a分配内存,并且将a初始化默认值,默认值:a=0
。将3正真的赋值 a = 3。
JVM运行时划分的区域:
程序最小单位是进程(数据不安全进程内的数据会被该进程内所有的线程共享),进程包含多个线程。
线程是进程最小的执行单位。
栈:只要符合栈结构,都遵循先进后出的原则
方法区 Method Area(进程)、非堆:类信息【类的创建时间、作者、元数据(数据描述信息)】、常量【final】、静态变量【static】、即时编译器编译后的代码。里面存储的是一些。类类型加载的东西(也就是反射中的.class之后的Class),用于存储已经被虚拟机加载的类的信息、常量、静态变量等。与堆一样,是被线程共享的内存区域,要注意线程安全问题。方法区逻辑上属于堆的一部分。如果存储数据大小超过了比方说1个G就会报OutOfMemoryError(OOM)异常。
堆 Heap(进程):代表某个类的java.lang.Class对象。存储对象、String、数组。如果存储数据大小超过了比方说1个G就会报OutOfMemoryError(OOM)异常。
Java虚拟机栈(线程):一个线程当中会有一个私有Java虚拟机栈。生命周期是与线程绑定在一起。存储Java方法。
在Java方法中如何去调用C语言的方法,通过动态链接去调用完成。
本地方法栈(线程):存储C语言方法。
栈帧(Java虚拟机栈、本地方法栈)Frame:代表是方法的执行。一个栈帧被创建就表示一个方法被执行,方法压栈先进后出。
//伪代码1
a(){
b();
}
b(){
c();
}
c(){ }
//先进行压栈
//先往Java虚拟机中压栈存入a(),之后是b(),在之后是c()。
//之后是出栈
//在c()方法执行完之后先出,b()执行完再出,最后是a()执行完再出。
//先进后出的概念。 //伪代码2
a(){
a();
}
//如果递归一直调用自己,超出栈的长度或深度,就会报StackOverflowError(栈溢出)。同理如果一个方法内部的调用链非常长或深的话也一样会报StackOverflowError(栈溢出)。
局部变量表:存储方法中的局部变量
操作数栈:栈结构,用来描述运算过程当中数据暂时的存储位置
//伪代码.java文件
public static int calc(int op1,int op2){
op1 = 3;
int result = op1 + op2;
return result;
}
//.java文件的.class文件翻译的JVM字节码。
public static int calc(int op1,int op2);
Code:
0:iconst_3 // 将3放到操作数栈中
//局部变量下标:如果是类级别方法【static修饰的方法】下标是从0开始;如果是实例方法下标从1开始,0标识的是这个实例,保留给当前对象的引用this。
1:istore_0 //将操作数占中的3赋值给局部变量表中的局部变量
2:iload_0 //将局部变量0值放到操作数栈中
3:iload_1 //
4:iadd
5:istore_2
6:iload_2
7:ireturn
动态链接:符号引用转换为直接引用**。动态的转换。比方说:一个方法调用某个接口或抽象类,这时是不知道这个方法内部具体实现的,只有等到程序运行时才能知道具体是调用了哪个子类或实现类的方法。
正常或异常方法的返回:
程序计数器(线程):是一块较小的内存空间,它可以看做是当前线程所执行的字节码的行号指示器。在虚拟机的概念模型里(仅是概念模型,各种虚拟机可能会通过一些更高效的方式去实现),字节码解释器工作时就是通过改变这个计数器的值来选取下一条需要执行的字节码指令,分支、循环、跳转、异常处理、线程恢复等基础功能都需要依赖这个计数器来完成。
JAVA 对象内存布局
对象头:
Mark Word:一系列的标记为(哈希码,分代年龄,锁状态标志等)64位系统:8字节
Class Pointer:指向对象对应的类元数据的内存地址 64位系统:8字节
Length数组对象特有:数组长度 4字节
实例数据:
包含了对象的所有成员变量,大小由各个变量类型决定
boolean和byte:1字节
short和char:2字节
int和float:4字节
long和double:8字节
reference:8字节(64位系统)
对齐填充:
为了保证对象的大小为8字节的整数倍,会进行填充字节
赵小胖个人博客
1-JVM基础的更多相关文章
- JVM 基础知识
JVM 基础知识(GC) 2013-12-10 00:16 3190人阅读 评论(1) 收藏 举报 分类: Java(49) 目录(?)[+] 几年前写过一篇关于JVM调优的文章,前段时间拿出来看了看 ...
- java 笔记(1)-—— JVM基础,内存数据,内存释放,垃圾回收,即时编译技术JIT,高精度类型
1.java中5个存放数据的地方: (1).寄存器(Registers):位于CPU内部,是速度最快的存储区,但是数量和容量有限.在java中不能直接操作寄存器. (2).栈(Stack):栈位于通用 ...
- JVM基础:深入学习JVM堆与JVM栈
转自:http://developer.51cto.com/art/201009/227812.htm JVM栈解决程序的运行问题,即程序如何执行,或者说如何处理数据;JVM堆解决的是数据存储的问题, ...
- JVM基础知识(1)-JVM内存区域与内存溢出
JVM基础知识(1)-JVM内存区域与内存溢出 0. 目录 什么是JVM 运行时数据区域 HotSpot虚拟机对象探秘 OutOfMemoryError异常 1. 什么是JVM 1.1. 什么是JVM ...
- Jvm基础(2)-Java内存模型
Jvm基础(2)-Java内存模型 主内存和工作内存 Java内存模型包括主内存和工作内存两个部分:主内存用来存储线程之间的共享变量:而工作内存中存储每个线程的相关变量. 如下图所示: 需要注意的是: ...
- 剑指Offer——知识点储备-JVM基础
剑指Offer--知识点储备-JVM基础 1.java内存与内存溢出 1.1 JVM分为哪些区,每一个区干嘛的?(见java虚拟机38页) (1)程序计数器(线程私有) 当前线程执行字节码的信号指示器 ...
- JVM基础系列第15讲:JDK性能监控命令
查看虚拟机进程:jps 命令 jps 命令可以列出所有的 Java 进程.如果 jps 不加任何参数,可以列出 Java 程序的进程 ID 以及 Main 函数短名称,如下所示. $ jps 6540 ...
- JVM基础系列第14讲:JVM参数之GC日志配置
说到 Java 虚拟机,不得不提的就是 Java 虚拟机的 GC(Garbage Collection)日志.而对于 GC 日志,我们不仅要学会看懂,而且要学会如何设置对应的 GC 日志参数.今天就让 ...
- JVM基础系列第13讲:JVM参数之追踪类信息
我们都知道 JVM 在启动的时候会去加载类信息,那么我们怎么得知他加载了哪些类,又卸载了哪些类呢?我们这一节就来介绍四个 JVM 参数,使用它们我们就可以清晰地知道 JVM 的类加载信息. 为了方便演 ...
- JVM基础系列第11讲:JVM参数之堆栈空间配置
JVM 中最重要的一部分就是堆空间了,基本上大多数的线上 JVM 问题都是因为堆空间造成的 OutOfMemoryError.因此掌握 JVM 关于堆空间的参数配置对于排查线上问题非常重要. tips ...
随机推荐
- 01FPGA设计流程
今天学习了FPGA设计流程的视频,我理解要做一个完整的FPGA系统,所要经历的步骤,先将它简单总结如下: 我在对上面的流程图进行解释: 第一:设计定义就是我们这个FPGA系统或者FPGA设计所要实现的 ...
- +load 和 +initialize
APP 启动到执行 main 函数之前,程序就执行了很多代码. 执行顺序: 将程序依赖的动态链接库加载到内存 加载可执行文件中的所有符号,代码 runtime 解析被编译的符号代码 遍历所有的 cla ...
- 「MoreThanJava」计算机发展史—从织布机到IBM
「MoreThanJava」 宣扬的是 「学习,不止 CODE」,本系列 Java 基础教程是自己在结合各方面的知识之后,对 Java 基础的一个总回顾,旨在 「帮助新朋友快速高质量的学习」. 当然 ...
- php源码的编译
本片文章主要介绍windows下的php源码的编译. 1.1 编译环境 软件 环境 操作系统 Windows 7 专业版 32bit Visual studio 2012 专业版 PHP 5.5.2. ...
- EF 太重,MyBatis 太轻,ORM 框架到底怎么选 ?
以 EF 为代表的基于 Linq 的 ORM 框架总是 很重. 他们的功能早已超出了一个 ORM 的范畴, ORM 是 Object Relational Mapping ,从名字上看,其初衷是将 数 ...
- FastJson反序列化和构造函数之间的一点小秘密
各位看官大家下午好,FastJson想必大家都很熟悉了,很常见的Json序列化工具.今天在下要和大家分享一波FastJson反序列化和构造函数之间的一点小秘密. 下面先进入大家都深恶痛绝的做题环节.哈 ...
- php simplexml_load_string 返回的对象print_r后,丢失信息?
<?php $content = '<dblp> <inproceedings key="conf/aaim/He07" mdate="2007- ...
- go 锁和sync包
一.什么是锁? sync.Mutex 是一个互斥锁,它的作用是守护在临界区入口来确保同一时间只能有一个线程进入临界区 在 sync 包中还有一个 RWMutex 锁:他能通过 RLock() 来允许同 ...
- javascript入门 之 Ajax(一)
1.在项目的根目录下创建data目录,data目录下创建info文件,编写info文件如下代码: <h1>all data<h2> <p>this is the d ...
- 【Canvas】(1)---概述+简单示例
Canvas---概述+简单示例 如果通俗的去理解Canvas,我们可以去理解成它类似于我们电脑自带的画图工具一样,canvas首先是选择一块画布,然后在这个画布上描绘我们想画的东西,画好后展示给用户 ...