【java学习】JVM学习

1,JVM

①JVM可以用软件/硬件实现。
②字节码是虚拟机的机器码。
③JVM将代码程序与各操作系统和硬件分开,JVM的存在使java可以跨平台。

2,JDK(Java Development Kit)

1)概念:

JDK是用于支持Java程序开放的最小环境。

2)组成:

Java程序设计语言、Java虚拟机、Java API类库等三部分组成。

3)包含组件:

①Javac.exe

是收录于JDK中的Java语言编译器。可以将后缀名为.java的源文件编译为后缀名为.class的可以运行于JVM的字节码。

②java

运行工具,运行.class的字节码

③jar

打包工具,将相关的类文件打包成一个文件

④javadoc

文档生成器,从源码注释中提取文档,注释需匹配规范

⑤jdb debugger

调试工具

⑥jps

显示当前java程序运行的进程状态

⑦javah

从Java类生成C头文件和C源文件。这些文件提供了连接胶合,使Java和C代码可进行交互。

4)Java类库(Java API)

Java官方为开发者提高的很多功能强大的类,分别放在各个包中。
Java类库具有跨平台的特点,保证了软件的可移植性。

①java.*开头:

java的核心包。

a>java.lang

java编程的基础类。如:Object,Math,String,StringBuffer,System,Thread等。

b>java.util

包含集合框架、遗留的集合类、事件模型、日期和时间实施、国际化和各自实用工具类(字符串标记生成器、随机数生成器)。

c>java.io

通过文件系统、数据流和序列化提供系统的输入与输出。

d>java.net

实现网络应用与开发的类。

e>java.sql

使用Java语言访问并处理存储再数据源(通常是一个关系型数据库)中的数据API

f>java.awt

GUI设计与开发的类:创建界面和绘制图形图像的所有类。

g>java.swing

GUI设计与开发的类:是一组轻量级的组件。

h>java.text

与自然语言无关的方式来处理文本、日期、数字和消息的类和接口。

②javax.*开头:

扩展包。x是extension的意思。是对java.*的优化和扩展。

③org.*开头:

是各个机构或组织发布的包。这些组织有影响力,且代码质量高。

④com.*开头:

由盈利性公司发布,有版权问题。
注意:为防止命名重复,惯例:以自己的域名倒写形式作为开头来为自己开发的包命名,如百度:com.baidu.*开头。

3,JRE(Java Runtime Environment)

1)概念:

JRE是支持Java程序运行的标准环境。

2)组成:

把Java API类库中的Java SE API子集和Java虚拟机这两部分统称为JRE。

4,Java内存

1)内存区域与内存溢出异常

Java虚拟机(Virtual Machine)所管理的内存包括的运行时数据区域(如下图):

i)程序计数器(Program Counter Register)

a>功能:

指示当前线程所执行的字节码的行号。

b>JVM的多线程的实现:

线程轮流切换并分配处理器执行时间。在任何一个确定的时刻,一个CPU(内核)都只会执行一条线程中的指令。因此,为了线程切换后能恢复到正确的执行位置,每条线程都需要有一个独立的程序计数器,故这类内存区域为“线程私有”内存。
如果线程正在执行一个:

①Java方法,PCR记录的是正在执行的VM字节码指令地址。
②Native方法,PCR值为Undefined。

c>特点:

此内存区域是唯一一个在Java虚拟机规范中没有规定任何OutOfMemoryError情况的区域。

ii)虚拟机栈(VM Stack)

线程私有,生命周期与线程相同。

a>功能:

为VM执行Java方法(也就是字节码)服务。

VM Stack描述的是Java方法执行的内存模型,每个方法在执行的同时都会创建一个栈帧(Stack Frame),用于存储局部变量表、操作数栈、动态链接、方法出口等信息。每一个方法从调用直至执行完成的过程,对应一个Stack Frame在VM Stack中入栈出栈的过程。

Java的内存并非简单的区分为Heap和Stack,实际远比这复杂。Stack指的是VM Stack,或者说是虚拟机中局部变量表部分。

局部变量表所需的内存空间在编译期间完成分配,进入方法时,方法所需在Stack Frame中分配的局部变量的空间是确定的,且在运行期间大小不变。

b>异常情况:

①StackOverflowError异常:线程请求的栈深度大于VM所允许的深度。

②OutOfMemoryError异常:JVM Stack动态扩展时,无法申请到足够的内存。

iii)本地方法栈(Native Method Stack)

功能:为VM使用Native方法服务。
其他与VM Stack一致。

iv)方法区(Method Area)

与Java Heap一样,是各个线程共享的内存区域。

a>功能:

存储已被JVM加载的类信息、常量、静态变量、即时编译器编译后的代码等数据。

b>运行常量池(Runtime Constant Pool):

是方法区的一部分。
Class文件:包含类的版本、字段、方法、接口等描述信息,还包括常量池(Constant Pool Table)信息,用于存放编译期生成的各种字面量和符号引用,这部分内容将在类加载后进入方法的运行时常量池中存放。

c>OutOfMemoryError异常:

常量池无法再申请到内存时抛出。

v)堆(Heap)

a>功能:

存放对象实例、数组。

b>特点:

由于JIT编译器的发展与逃逸分析技术的成熟,栈上分配、标量替换优化技术的发生,对象的分配也不一定就在堆上。

Java堆是GC管理的主要区域,故很多时候被称为“GC堆”。

Java堆可以处于物理上不连续的内存空间中。

Java Heap是JVM所管理的内存中最大的一块,是被所有线程共享的一块内存区域,在VM启动时创建。

vi)JVM对象:

a>对象的创建

VM遇到new指令->检查指令的参数是否能在常量池中定位到一个类的符号引用->检查这个符号引用代表的类是否被加载、解析和初始化过(如果没有,先执行相应的类加载过程)->VM为新对象分配内存(所需内存大小在加载完成后便可确定)->init方法

b>内存溢出异常:

Heap种的对象数量到达最大堆的容量限制后抛出。

2)内存管理

i>内存分配

为变量分配内存空间。

a)类变量和实例变量

①类变量

当类创建好后,类变量也随之创建好,无论创建多少个实例来引用访问类变量,底层都是对本类的引用。

②实例变量

为java对象所有,每次创建Java对象都会为它分配内存,并初始化。

b)基本类型与引用类型

①基本类型

在栈中分配内存,值保存于栈中。

②引用类型

在栈中保存变量指针,指向堆中的对象。

ii>内存回收

【java学习】垃圾回收机制(GC)、与C#对比、JVM内存学习

5,.class类

1)文件内容:

class文件是以8位字节为基础单位的二进制流,各个数据项目严格按照顺序紧凑地排列在class文件之中,中间没有添加任何分隔符。

2)文件结构:

(1-4)每个Class文件的头4个字节称为魔数(Magic Number),用来确定是Class文件。

(5-8)紧接着魔数之后的4个字节为:Class文件的版本号。(5-6)字节为此版本号(Minor Version),(7-8)为主版本号(Major Version)。

(9…)紧接着版本号之后为常量池入口。常量池可以理解为Class文件种的资源仓库。

(…)紧接着的2个字节代表访问标志。用于识别一些类或者接口层次的访问信息。

(…)+类索引+父类索引+接口索引集合…

3)编译

以下代码保存到B.java文件中:

class A{
    public static void main(String args[]){
        System.out.println("Hello world");
    }   
}

是合法的,但是无法运行。
原因:运行时,先编译B.java文件,通过。在B.class文件中找java的入口方法main,找不到。因为通过javac B.java命令编译后只会产生一个A.class文件(编译时,产生的.class文件名与类名相同)。

public static void main(String[] args){}方法是java程序的入口方法,其他main方法不是,并且这个入口方法必须被定义在类名与文件名相同的public类中。

一个文件内部可以有多个类的存在,但只有被public修饰的类的名字与文件的名字相同,其他类的名字可以根据需求随意起名字。

6,VM加载机制

1)定义:

VM将描述类的数据从Class文件加载到内存,并堆数据进行校验、转换解析和初始化,最终形成可以被VM直接使用的Java类型。

2)过程:

类型的加载、连接、初始化过程都是在程序运行期间完成的,这样做虽然在加载种增加了性能开销,但是提高了Java应用程序的灵活性(可以动态扩展的语言特性)。

Java Heap是JVM所管理的内存中最大的一块,是被所有线程共享的一块内存区域,在VM启动时创建。

字节码是虚拟机的机器码。

7,Dalvik Virtual Machine(DVM)

1)定义:

Android中的所有Java程序都是运行在Dalvik VM上的。Android上的每个程序都有自己的线程,DVM只执行.dex的Dalvik executable 文件。每个Android应用在底层都对应有一个独立的DVM实例并在其解释下执行。

是android4.0以下操作系统的主要的组成部分,Android Runtime中的元件包含:核心函数库(Core Libraries)、DVM。android4.4时被ART取代。

2)JVM与DVM区别:

①Java VM是以基于栈的虚拟机(Stack-based),而Dalvik是基于寄存器的虚拟机(Register-based)。显然,后者最大的好处在于可以根据硬件实现更大的优化,缩短编译时间,这更适合移动设备的特点。

②运行环境——Dalvik经过优化,允许在有限的内存中同时运行多个虚拟机的实例,并且每一个 Dalvik应用作为一个独立的Linux进程执行。独立的进程可以防止在虚拟机崩溃的时候所有程序都被关闭。

3)DVM与ART区别:

①DVVM是执行的时候编译+运行,安装快,开启应用慢,应用占用空间小。ART是安装的时候就编译好了,执行时直接运行,所以安装慢、开启应用快,占用空间大。

②ART(Ahead-Of-Time compiler):相比 ios,android卡的主要原因就是系统和应用层之间还有一层虚拟机,加入ART可提高系统整体的流畅性。

你可能感兴趣的:(java,jvm)