JVM简介及类加载机制(一)
JVM介绍:
目标:JVM运行字节码文件,根据JVM的日志调节程序,对于底层原理有一定的了解
1. 类加载
在JAVA代码中,类型的加载,连接与初始化都是在程序运行期间完成的,提供了灵活性增加了更多的可能性
2. 类加载器(加载类的工具)
虚拟机结束生命周期的情况
A) 执行System.exit(),finally中的代码都不能执行
B) 程序正常结束
C) 程序在执行过程当中碰到异常或异常终止
D) 操作系统出现错误
3.类的加载,连接,初始化
加载:查找并加载类的二进制(把类的二进制文件加载到内存里面)
连接:
A) 验证:确保加载类的正确性
B) 准备:为类的静态变量分配内存,并将其初始化为默认值
例子:
Class Test{
public static int a=1;
}
这个阶段将赋予a默认值0,赋值阶段在后面完成
C) 解析:把类中的符号引用转换为直接引用
符号引用:一个方法里面引用令一个方法
直接引用:指针直接指向方法的内存中的地址
初始化阶段:为类的静态变量分配正确的值,如上例中将1赋值给a
4.类的使用和卸载
类的使用分为主动使用和被动使用
所有的java虚拟机实现必须在每个类或接口被java”首次主动使用”(静态代码块只执行 一次)时才初始化他们
主动使用:
A) 创建类的实例(new 一个对象)
B) 访问某个类或接口的静态变量,或对该静态变量赋值
C) 调用类的静态方法
D) 反射(Class.forName(Class clazz))
E) 初始化一个类的子类(初始化子类时会先初始化父类)
F) Java虚拟机启动时被标明为启动类的类
G) 1.7以后提供了动态语言的支持
被动使用:
除了以上7种都是被动使用,不会导致类的初始化
5.类的加载
将.class的二进制数据读入内存当中,并将其放在运行时数据区的方法区内,然后在内存中创建java.lang.Class对象,用来封装类在方法区的数据结构
6.加载.class的方式
A)从本地系统直接加载
B)网络下载.class文件
C)压缩包里面下载
D)将java源文件动态编译成.class文件(动态代理)
下面来看个例子1:
public class Test1 {
public static void main(String[] args) {
System.out.println(MyChild.str);
}
}
class MyParent{
public static String str="hello world";
static{
System.out.println("myparent block");
}
}
class MyChild extends MyParent{
static{
System.out.println("mychild block");
}
}
console
myparent block
hello world
再看看下面这个
public class Test1 {
public static void main(String[] args) {
System.out.println(MyChild.str2);
}
}
class MyParent{
public static String str="hello world";
static{
System.out.println("myparent block");
}
}
class MyChild extends MyParent{
public static String str2="hello world11";
static{
System.out.println("mychild block");
}
}
console
myparent block
mychild block
hello world11
注:在子类在初始化是要先初始化父类
-XX:+TraceClassLoading 打印加载类的信息
+表示开关
例子2:
public class Test2 {
public static void main(String[] args) {
System.out.println(MyParent1.str);
}
}
class MyParent1{
public static String str="hello";
static{
System.out.println("parent block");
}
}
这个结果不必多说
parent block
hello
如果静态变量加了final呢?
public class Test2 {
public static void main(String[] args) {
System.out.println(MyParent1.str);
}
}
class MyParent1{
public static final String str="hello";
static{
System.out.println("parent block");
}
}
console
hello
那是因为什么呢?原因很简单
那就是常量在编译阶段就会存入到调用该常量的方法的类的常量池当中
下面说一些助记符的意义
ldc表示将int,float或是string类型的常量值从常量池中推送至栈顶(马上就要使用)
Blpush:表示字节(-128-127)的常量推送至栈顶
Sipush:将短整形常量值推送至栈顶
Iconst_1表示将int型的数字1推送至栈顶(Iconst_1-Iconst_5)
那再来看看下面这个例子3
public class Test3 {
public static void main(String[] args) {
System.out.println(MyParent2.str);
}
}
class MyParent2{
public static String str=UUID.randomUUID().toString();
static{
System.out.println("parent block");
}
}
console
parent block
6eb597fb-e999-40f8-8dc9-bf57c9124914
不知道结果与你的预期是否相同?
原因:当一个常量的值在编译期间不能确定,那么七值就不会放到调用类的常量池当中。这时当程序在运行时,会导致主动使用这个常量所在的类,就会导致该类初始化
下面再来看一个例子
public class Test4 {
public static void main(String[] args) {
//MyParent4 m4=new MyParent4();
MyParent4[] m4=new MyParent4[1];
}
}
class MyParent4{
static{
System.out.println("parent block");
}
}
这代表了什么?
MyParent4[] m4=new MyParent4[1];这个并不会主动使用
对于数组来说,其类型时JVM再运行期间动态生成的
JVM简介及类加载机制(一)的更多相关文章
- 【JVM】JVM系列之类加载机制(四)
一.前言 前面分析了class文件具体含义,接着需要将class文件加载到虚拟机中,这个过程是怎样的呢,下面,我们来仔细分析. 二.什么是类加载机制 把class文件加载到内存,并对数据进行校验.转换 ...
- JVM之虚拟机类加载机制
有兴趣可以先参考前面的几篇JVM总结: JVM自动内存管理机制-Java内存区域(上) JVM自动内存管理机制-Java内存区域(下) JVM垃圾收集器与内存分配策略(一) 我们知道,在编写一 ...
- 图解JVM和Tomcat类加载机制
说到本篇的tomcat类加载机制,不得不说翻译学习tomcat的初衷. 之前实习的时候学习javaMelody的源码,但是它是一个Maven的项目,与我们自己的web项目整合后无法直接断点调试.后来同 ...
- 深入理解JVM,虚拟机类加载机制
类加载过程概览 类从被加载到虚拟机内存中开始,到卸载出内存为止,它的整个生命周期包括以下7个阶段: 加载(Loading) 验证(Verification) 准备(Preparation) 解析(Re ...
- Java面试题:JVM中的类加载机制
JVM 的类加载机制是指 JVM 把描述类的数据从 .class 文件加载到内存,并对数据进行校验.转换解析和初始化,最终形成可以被虚拟机直接使用的 Java 类型,这就是 JVM 的类加载机制. 类 ...
- 【JVM】虚拟机类加载机制
什么是类加载 虚拟机把描述类的数据从Class文件加载到内存,并对数据进行校验.转换解析和初始化,最终形成可以被虚拟机直接使用的Java类型,这就是虚拟机的类加载机制. <[JVM]类文件结构& ...
- jvm之java类加载机制和类加载器(ClassLoader),方法区结构,堆中实例对象结构的详解
一.类加载或类初始化:当程序主动使用某个类时,如果该类还未被加载到内存中,则JVM会通过加载.连接.初始化3个步骤来对该类进行初始化.如果没有意外,JVM将会连续完成3个步骤. 二.类加载时机: 1 ...
- JVM之Java类加载机制
什么是类加载机制 虚拟机把描述类的数据从Class文件加载到内存,并对数据进行校验.转换解析和初始化,最终形成可以被虚拟机直接使用的Java类型,这既是虚拟机的类加载机制 类的生命周期 生命周期简述 ...
- jvm系列 (五) ---类加载机制
类的加载机制 目录 jvm系列(一):jvm内存区域与溢出 jvm系列(二):垃圾收集器与内存分配策略 jvm系列(三):锁的优化 jvm系列 (四) ---强.软.弱.虚引用 我的博客目录 什么是类 ...
随机推荐
- iOS 技能图谱
# iOS 技能图谱## 编程语言 - Swift - Objective-C - C++/C - JavaScript ## 操作系统 - Mac OSX - iOS - watchOS - tvO ...
- NMS python实现
import numpy as np ''' 目标检测中常用到NMS,在faster R-CNN中,每一个bounding box都有一个打分,NMS实现逻辑是: 1,按打分最高到最低将BBox排序 ...
- mac 密码重置
首先请开机或重新启动系统,在电脑刚启动时,请按下键盘上的 command+S 组合键不动, 接下来会在屏幕上看到一串串的命令字符显示,当进入安全模式以后,会看到 一个 root 开始的命令行输入端口. ...
- LLppdd has a dream!
LLppdd has a dream Time Limit: 3 s Memory Limit: 256 MB 题目背景 LLppdd经过他充满坎坷的初三后,他的成绩也充满了坎坷. 临近中考了,他希望 ...
- ArrayList的几种初始化方法
1.使用Arrays.asList方法 ArrayList<Object> obj = new ArrayList<Object>(Arrays.asList(Object o ...
- Android开发 Butterknife使用方法总结
前言: ButterKnife是一个专注于Android系统的View注入框架,以前总是要写很多findViewById来找到View对象,有了ButterKnife可以很轻松的省去这些步骤.是大神J ...
- iptables 防火墙(下)
iptables 防火墙(下) 1. 常见的隐含匹配条件: 1.1 端口匹配: --sport 源端口.--dport 目的端口 1.2 TCP标记匹配: -tcp-flags 检查范围被设置的标记 ...
- CICS FILE OPEN
CEMT I CECD V FILE() GROUP() CEDA check error log in JESYSMSG FILE OPEN/CLOSE STATUS CICS ACTION res ...
- eclipse发布路径变更
但是其默认访问的目录是eclipse临时目录而非Tomcat目录, 建议双击tomcat進入配制界面Service Locations 修改选项为:Use Tomcat installation(ta ...
- 安装配置oh-my-zsh
1.下载安装iterm:https://www.iterm2.com/ 2.安装zsh 查看系统当前使用的shell $ echo $SHELL /bin/bash 查看系统是否安装了zsh $ ca ...