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系列 (四) ---强.软.弱.虚引用 我的博客目录 什么是类 ...
随机推荐
- Hexo next 添加复制粘贴代码的功能
文章目录 广告: 自己的方式 感谢 广告: 本人博客地址:https://mmmmmm.me 源码:https://github.com/dataiyangu/dataiyangu.github.io ...
- 25. Postman的使用
Postman下载与安装 不管是接口测试人员还是开发人员大概率下都绕不开一个工具,那就是Postman.当然可能还有一些接口测试工具,比如soapUI.Jmeter.Robot Framework 等 ...
- 转 MySQL数据库面试问题集锦
如何设计一个高并发的系统 ① 数据库的优化,包括合理的事务隔离级别.SQL语句优化.索引的优化 ② 使用缓存,尽量减少数据库 IO ③ 分布式数据库.分布式缓存 ④ 服务器的负载均衡 锁的优化策略 ① ...
- hduoj-1301 Jungle Roads(最小生成树-克鲁斯卡尔和普里姆求解)
普里姆求解: #include<cstdio> #include<cmath> #include<cstring> #include<iostream> ...
- python之模块导入方法总结
模块在python编程中的地位举足轻重,熟练运用模块可以大大减少代码量,以最少的代码实现复杂的功能. 下面介绍一下在python编程中如何导入模块: (1)import 模块名:直接导入,这里导入模块 ...
- [轉]udp_sendmsg空指针漏洞分析 by wzt
udp_sendmsg空指针漏洞分析 by wzt 漏洞描述: 由于Linux ipv4协议栈中udp_sendmsg()函数设计上存在缺陷, 导致struct rtable *rt以空指针形式 ...
- Python之switch
首先声明,Python没有switch!!! 通过函数与字典的结合实现 #!/usr/bin/python #coding:utf-8 from __future__ import division ...
- python之将Unicode文本标准化
在需要比较字符串的程序中使用字符的多种表示会产生问题. 为了修正这个问题,你可以使用unicodedata模块先将文本标准化: s1 = 'Spicy Jalape\u00f1o' s2 = 'Spi ...
- android5.1 隐藏状态栏
修改frameworks/base/core/res/res/values/dimens.xml文件中 <!-- Height of the status bar --> <!-- ...
- 使用vscode搭建本地的websocket
首先在服务器方面,网上都有不同的对websocket支持的服务器: php - http://code.google.com/p/phpwebsocket/ jetty - http://jetty. ...