①JVM可以用软件/硬件实现。
②字节码是虚拟机的机器码。
③JVM将代码程序与各操作系统和硬件分开,JVM的存在使java可以跨平台。
JDK是用于支持Java程序开放的最小环境。
Java程序设计语言、Java虚拟机、Java API类库等三部分组成。
是收录于JDK中的Java语言编译器。可以将后缀名为.java的源文件编译为后缀名为.class的可以运行于JVM的字节码。
运行工具,运行.class的字节码
打包工具,将相关的类文件打包成一个文件
文档生成器,从源码注释中提取文档,注释需匹配规范
调试工具
显示当前java程序运行的进程状态
从Java类生成C头文件和C源文件。这些文件提供了连接胶合,使Java和C代码可进行交互。
Java官方为开发者提高的很多功能强大的类,分别放在各个包中。
Java类库具有跨平台的特点,保证了软件的可移植性。
java的核心包。
java编程的基础类。如:Object,Math,String,StringBuffer,System,Thread等。
包含集合框架、遗留的集合类、事件模型、日期和时间实施、国际化和各自实用工具类(字符串标记生成器、随机数生成器)。
通过文件系统、数据流和序列化提供系统的输入与输出。
实现网络应用与开发的类。
使用Java语言访问并处理存储再数据源(通常是一个关系型数据库)中的数据API
GUI设计与开发的类:创建界面和绘制图形图像的所有类。
GUI设计与开发的类:是一组轻量级的组件。
与自然语言无关的方式来处理文本、日期、数字和消息的类和接口。
扩展包。x是extension的意思。是对java.*的优化和扩展。
是各个机构或组织发布的包。这些组织有影响力,且代码质量高。
由盈利性公司发布,有版权问题。
注意:为防止命名重复,惯例:以自己的域名倒写形式作为开头来为自己开发的包命名,如百度:com.baidu.*开头。
JRE是支持Java程序运行的标准环境。
把Java API类库中的Java SE API子集和Java虚拟机这两部分统称为JRE。
Java虚拟机(Virtual Machine)所管理的内存包括的运行时数据区域(如下图):
指示当前线程所执行的字节码的行号。
线程轮流切换并分配处理器执行时间。在任何一个确定的时刻,一个CPU(内核)都只会执行一条线程中的指令。因此,为了线程切换后能恢复到正确的执行位置,每条线程都需要有一个独立的程序计数器,故这类内存区域为“线程私有”内存。
如果线程正在执行一个:
此内存区域是唯一一个在Java虚拟机规范中没有规定任何OutOfMemoryError情况的区域。
线程私有,生命周期与线程相同。
为VM执行Java方法(也就是字节码)服务。
VM Stack描述的是Java方法执行的内存模型,每个方法在执行的同时都会创建一个栈帧(Stack Frame),用于存储局部变量表、操作数栈、动态链接、方法出口等信息。每一个方法从调用直至执行完成的过程,对应一个Stack Frame在VM Stack中入栈出栈的过程。
Java的内存并非简单的区分为Heap和Stack,实际远比这复杂。Stack指的是VM Stack,或者说是虚拟机中局部变量表部分。
局部变量表所需的内存空间在编译期间完成分配,进入方法时,方法所需在Stack Frame中分配的局部变量的空间是确定的,且在运行期间大小不变。
①StackOverflowError异常:线程请求的栈深度大于VM所允许的深度。
②OutOfMemoryError异常:JVM Stack动态扩展时,无法申请到足够的内存。
功能:为VM使用Native方法服务。
其他与VM Stack一致。
与Java Heap一样,是各个线程共享的内存区域。
存储已被JVM加载的类信息、常量、静态变量、即时编译器编译后的代码等数据。
是方法区的一部分。
Class文件:包含类的版本、字段、方法、接口等描述信息,还包括常量池(Constant Pool Table)信息,用于存放编译期生成的各种字面量和符号引用,这部分内容将在类加载后进入方法的运行时常量池中存放。
常量池无法再申请到内存时抛出。
存放对象实例、数组。
由于JIT编译器的发展与逃逸分析技术的成熟,栈上分配、标量替换优化技术的发生,对象的分配也不一定就在堆上。
Java堆是GC管理的主要区域,故很多时候被称为“GC堆”。
Java堆可以处于物理上不连续的内存空间中。
Java Heap是JVM所管理的内存中最大的一块,是被所有线程共享的一块内存区域,在VM启动时创建。
VM遇到new指令->检查指令的参数是否能在常量池中定位到一个类的符号引用->检查这个符号引用代表的类是否被加载、解析和初始化过(如果没有,先执行相应的类加载过程)->VM为新对象分配内存(所需内存大小在加载完成后便可确定)->init方法
Heap种的对象数量到达最大堆的容量限制后抛出。
为变量分配内存空间。
当类创建好后,类变量也随之创建好,无论创建多少个实例来引用访问类变量,底层都是对本类的引用。
为java对象所有,每次创建Java对象都会为它分配内存,并初始化。
在栈中分配内存,值保存于栈中。
在栈中保存变量指针,指向堆中的对象。
【java学习】垃圾回收机制(GC)、与C#对比、JVM内存学习
class文件是以8位字节为基础单位的二进制流,各个数据项目严格按照顺序紧凑地排列在class文件之中,中间没有添加任何分隔符。
(1-4)每个Class文件的头4个字节称为魔数(Magic Number),用来确定是Class文件。
(5-8)紧接着魔数之后的4个字节为:Class文件的版本号。(5-6)字节为此版本号(Minor Version),(7-8)为主版本号(Major Version)。
(9…)紧接着版本号之后为常量池入口。常量池可以理解为Class文件种的资源仓库。
(…)紧接着的2个字节代表访问标志。用于识别一些类或者接口层次的访问信息。
(…)+类索引+父类索引+接口索引集合…
以下代码保存到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修饰的类的名字与文件的名字相同,其他类的名字可以根据需求随意起名字。
VM将描述类的数据从Class文件加载到内存,并堆数据进行校验、转换解析和初始化,最终形成可以被VM直接使用的Java类型。
类型的加载、连接、初始化过程都是在程序运行期间完成的,这样做虽然在加载种增加了性能开销,但是提高了Java应用程序的灵活性(可以动态扩展的语言特性)。
Java Heap是JVM所管理的内存中最大的一块,是被所有线程共享的一块内存区域,在VM启动时创建。
字节码是虚拟机的机器码。
Android中的所有Java程序都是运行在Dalvik VM上的。Android上的每个程序都有自己的线程,DVM只执行.dex的Dalvik executable 文件。每个Android应用在底层都对应有一个独立的DVM实例并在其解释下执行。
是android4.0以下操作系统的主要的组成部分,Android Runtime中的元件包含:核心函数库(Core Libraries)、DVM。android4.4时被ART取代。
①Java VM是以基于栈的虚拟机(Stack-based),而Dalvik是基于寄存器的虚拟机(Register-based)。显然,后者最大的好处在于可以根据硬件实现更大的优化,缩短编译时间,这更适合移动设备的特点。
②运行环境——Dalvik经过优化,允许在有限的内存中同时运行多个虚拟机的实例,并且每一个 Dalvik应用作为一个独立的Linux进程执行。独立的进程可以防止在虚拟机崩溃的时候所有程序都被关闭。
①DVVM是执行的时候编译+运行,安装快,开启应用慢,应用占用空间小。ART是安装的时候就编译好了,执行时直接运行,所以安装慢、开启应用快,占用空间大。
②ART(Ahead-Of-Time compiler):相比 ios,android卡的主要原因就是系统和应用层之间还有一层虚拟机,加入ART可提高系统整体的流畅性。