虚拟机

2017-09-19  本文已影响0人  小酷哥

http://www.bubuko.com/infodetail-2242063.html

1996 jdk1.0 (classic vm 虚拟机)
1997 jdk1.1
1998 jdk1.2 (javaee,javase区分)
2000 jdk1.3 (hotspot虚拟机发布)
2002 jdk1.4 (解密类库,正则表达式)
2004 jdk1.5 (泛型,注解,装箱,枚举)
2004 jdk1.6 (jdbc4.0,脚本语言支持)
2011 jdk1.7 (新的垃圾回收器G1)
2014 jdk1.8 (Lambda表达式)
2016 jdk1.9 (模块化)

oracle 两个虚拟机 JRockit和HotSpot。jdk8要进行整合成一个。

只要符合jvm语言规范的标准,什么语言都可以在jvm中运行。

jvm保存数据使用的是2进制,2进制是8位,第一位是符合位,1代表负数。

jvm为什么要使用补码? (正负数的补码相同)
正数的原码,反码,补码均相同。
负数的反码在原码的基础上,最高位(符号位)不变,其他位0变1,1变0,补码再在反码的基础上加1
0
正数:0000 0000

负数:1000 0000
反码:1111 1111
补码:0000 0000

-6+5 的运算?
-6的原码:1000 0110
-6的反码:1111 1001 (+1获得补码)
-6的补码:1111 1010

5的原码:0000 0101
5的补码:0000 0101

1111 1010

jvm内存空间
堆 :1.对象实例 2.线程共享 3.GC主要工作区 4.数组 5.堆的划分
方法区 :
虚拟机栈 :1.线程私有 2.栈是由栈帧组成,每个帧是一个方法(静态和非静态)。3.局部变量
Native栈 :
计数器 :

对象的栈上分配:1)小对象 2)直接分配在栈上,可以自动回收,减轻gc压力

可见性:一个线程修改了变量,其他线程可以立刻知道
保证可见性的方法:
1)volatile :
2)synchronized
3)final : 被定义成常量的变量

线程的分类
1)守护线程:jvm自己使用的线程,例如:gc线程
2)普通线程:jvm中只要还存在普通线程,jvm就不会停止。

jvm加载并解析一个类后,将类信息保存到方法区,创建的对象保存对堆中。(方法区和堆是内存共享的)。
当一个线程被创建时,会被分配一个程序计数器(pc寄存器)和 虚拟机栈。虚拟机栈保存了该线程调用方法状态,
一个方法一个栈帧,里面保存了方法的局部变量,方法参数,返回值。当方法执行时,该帧进入栈,当执行完成,
帧出栈。计数器保存该线程执行的行号。

堆:
当创建一个类的实例或者数组时,都在堆中为新对象分配内存。jvm中只要一个堆,所有的线程都共享他。

jvm的生命周期:
执行java程序,程序开始执行jvm开始运行,当程序结束时它就停止。
同一台机子上运行三个程序,就会运行三个jvm。java的线程分两种,
守护线程和普通线程。只有当jvm中没有普通线程执行时,jvm就会停止。
守护线程是jvm自己使用的线程,比如GC线程。

1个字节 占8位
int 4个字节 32位

15.为什么要使用16进制?
人写的是10进制,转换为2进制的话,是32位太长了。
使用16进制就短了很多

16.class文件结构
魔数(4字节)+ class文件版本号(4个字节)+常量池 + 访问标志

常量池 = 字面量(字符串和常量) + 符号引用(类信息+方法描述)

17.操作数栈和寄存器的架构区别?

18.类加载时期:
加载 验证 准备 解析 初始化 使用 卸载

19.类进行初始化的时机?
主动引用(会进行初始化)
1)使用new关键字实例化对象
2)读取一个类的静态字段
3)调用一个类的静态方法
4)使用反射调用类
5)子类初始化时,发现父类未初始化,父类进行初始化
6)包含main()方法的主类
被动引用(不会进行初始化)
1)通过子类引用父类的静态字段,不会导致子类初始化
2)通过数组定义来引用类,不会触发此类的初始化 SupperClass[] sc = new SupperClass[10];
3) 使用(public static final String XXX)修饰的常量,不会初始化该类。

20.类的加载的过程,jvm需要做的事?
1)通过类全名获取该类的2进制流
2)将字节流转换为方法区可识别的数据结构
3)在堆中创建该对象,作为方法区这个类的访问入口。

21.类的验证过程?
主要目的就保证class文件符合jvm规范标准
1)文件格式验证(魔数,主次版本号,常量池)
2)元数据验证

22.类的准备过程?
为类变量(static修饰的)分配内存并设初始值(数据类型的初始值0)。
这个阶段内存分配仅包括类变量,不包括实例变量,实例变量将会在对象
实例化时,随着对象一起分配到java堆中。

23.类的初始化?
开始执行类中程序代码

24.类加载器

25.栈帧结构:

  1. 通过javap指令来获取类的字节码

  2. 可以眼看反编译class文件到java文件

  3. mat来检测内存溢出,lint 检测代码规范

  4. 内存溢出:

  1. 内存管理,内存优化,oom

  2. 图片缓存的两种方式:软引用,Lru算法

  3. Lint进行代码检测 mat进行内存溢出检测

  4. 内存优化

上一篇下一篇

猜你喜欢

热点阅读