文档库 最新最全的文档下载
当前位置:文档库 › 深入理解Java虚拟机笔记(带目录)

深入理解Java虚拟机笔记(带目录)

深入理解Java虚拟机笔记(带目录)
深入理解Java虚拟机笔记(带目录)

目录

1.虚拟机内存结构 (1)

2.对象在内存中的布局 (3)

3.判断对象是否死亡 (4)

4.引用的4中情况 (4)

5.垃圾收集算法 (5)

6.HotSpot虚拟机算法实现 (6)

7.如何在GC发生时让所有线程都要附近的安全点停下 (6)

8.垃圾收集器 (7)

9.GC日志 (9)

10.内存分配 (10)

11.Class类文件的结构 (10)

12.类的生命周期 (13)

13.类加载器 (15)

14.运行时栈帧的结构 (16)

15. 方法调用 (18)

16. 分派 (19)

17.虚方法表 (19)

18.Java内存模型(JMM) (19)

19.内存间的交互 (20)

20.volatile变量 (20)

21.原子性 (21)

22.可见性 (22)

23.有序性 (22)

24.先行发生原则 (22)

25.Java线程调度 (23)

26.线程的状态 (24)

27.线程安全 (25)

28.线程安全的实现方法 (26)

29.锁优化 (27)

30.编译优化技术 (29)

1.虚拟机内存结构

线程私有:虚拟机栈,本地方法栈,程序计数器

线程共享:堆,方法区(包括运行时常量池)

1.1程序计数器

当前程序锁执行的字节码行号指示器,记录下一条需要执行的

指令。

1.2虚拟机栈

生命周期与线程相同,每个方法在执行时都会创建一个栈帧。

方法执行的过程,就是栈帧入栈到出栈的过程。

栈帧用于存放局部变量表,操作数栈,动态链接,方法出口等

信息。

局部变量表存放了编译期可知的基本数据类型和对象引用。1.3 本地方法栈

为虚拟机使用到的Native方法服务。

目前HotSpot虚拟机将本地方法栈和虚拟机栈合二为一。

1.4堆

存放对象实例,所有线程共享。

1.5 方法区(永久代)

存放被虚拟机加载的类信息,常量,静态变量,即时编译器编

译后的代码等。

1.6 运行时常量池

方法区的一部分,用于存放编译期生成的各种字面量和符号引用。

1.7 字面量,符号引用,直接引用

字面量:

通俗解释就是一个变量的值,但是这个值不能超过范围。

int a = 1; 1是a的字面量

213738648则不能是int的字面量,因为超出了int的范围。

符号引用:

以一组符号来描述引用的目标,符号可以是任何形式的

字面量,只要使用时能够无歧义的定位到目标即可。

直接引用:

直接指向目标的指针(类变量,类方法)。

相对偏移量(实例变量,实例方法)。

一个能间接定位到目标的句柄。

2.对象在内存中的布局

对象头(哈希码,GC分代年龄,数据指针,如果是数组还会有数组长度),实例数据,对齐填充

3.判断对象是否死亡

3.1引用计数算法

每个对象添加一个计数器,引用它加1,引用失效减1,为0则死亡,很难解决循环引用问题。

3.2可达性分析算法

从gc root节点开始向下搜索,不可达则已死。

可作为gc root节点的情况:

3.2.1:虚拟机栈本地变量表引用的对象

3.2.2:方法区中类静态属性引用的对象

3.2.3:方法区中常量引用的对象

3.2.4:本地方法栈native方法引用的对象

4.引用的4中情况

强引用,软引用,弱引用,虚引用(幽灵引用)

4.1强引用:new 关键字,强引用还在,则不会被回收

4.2软引用:发生内存溢出钱,会把这些软引用对象列入回收范围

进行第二次回收时会将他们回收

4.3:弱引用:只能存活到下一次垃圾回收之前

4.4:虚引用:与对象的生存时间不发生关系,作用是在这个对象

被回收的时候,收到一个系统通知

5.垃圾收集算法

5.1:标记—清除Mark-Sweep

过程:标记可回收对象,进行清除

缺点:标记和清除效率低,清除后会产生内存碎片

5.2:复制算法

过程:将内存划分为相等的两块,将存活的对象复制到另一块内存,把已经使用的内存清理掉

缺点:使用的内存变为了原来的一半

进化:将一块内存按8:1的比例分为一块Eden区(80%)和两块Survivor区(10%)

每次使用Eden和一块Survivor,回收时,将存活的对象一次性复制到另一块Survivor上,如果另一块Survivor空间不足,则使用分配担保机制存入老年代

5.3:标记—整理Mark—Compact

过程:所有存活的对象向一端移动,然后清除掉边界以外的内存

5.4:分代收集算法

过程:将堆分为新生代和老年代,根据区域特点选用不同的收集算法,如果新生代朝生夕死,则采用复制算法,老年代采用标记清除,或标记整理

6.HotSpot虚拟机算法实现

6.1枚举根节点

回收时如果逐个检查引用(可达性分析)效率低下,通过OopMap 数据结构来得知哪些地方存放着引用

6.2安全点

不会为所有指令都生成OopMap,只会在特定位置生成,这些位置成为安全点。

方法调用,循环跳转,异常跳转等会产生安全点

7.如何在GC发生时让所有线程都要附近的安全点停下

7.1抢先式中断

中断全部线程,如果发现有线程不在安全点上,那么恢复线程,让它跑到安全点上(几乎不使用)

7.2主动式中断

设置一个标志,线程执行时去轮询这个标志,标志为true则线程挂起。标志和安全点是重合的

7.3安全区域

一段代码片段,在这个区域中的任意地方开始GC都是安全的。为了解决处于Sleep或Blocked线程达到安全点的问题。

过程:如果进入到了安全区域,那么标识自己已经进入,GC时不用管已经标识过的。如果离开,则检查是否完成了节点枚举或者整个GC,如果未完成,则必须等待离开信号。

8.垃圾收集器

8.1Serial

单线程新生代收集器,只会用一条线程完成收集工作

在Client模式下的虚拟机可以选择

新生代:复制算法

老年代:标记—整理

8.2ParNew

Serial的多线程版本,收集过程以及算法与Serival一致,可与CMS

老年代收集器配合

8.3 Parallel Scavenge

新生代收集器,多线程,主要关注吞吐量

适合在后台运算不需要太多交互的任务

采用复制算法

8.4 Serial Old

Serial 的老年代版本,采用标记—整理

8.5Parallel Old

Parallel Scavenge的老年代版本,采用多线程标记—整理

8.6 CMS

老年代收集器,关注停顿时间,采用标记—清除

4个过程,初始标记,并发标记,重新标记,并发清除

收集过程与用户线程并发执行

缺点:并发收集占用CPU资源,降低吞吐率。

浮动垃圾,程序不断运行会产生新的垃圾。

JDK1.5老年代占用达到68%会触发,JDK1.6老年代占用达

到92%会触发,触发的阈值可以设置,设置不当会导致FuLL

GC降低性能。

会出现内存碎片,可设置参数,多少次不压缩的Full GC之

后,进行一次压缩的,默认0,每次都会压缩。

8.7 G1

特点:并行与并发,分代手机,空间整合,可预测的停顿

将Java堆分为多个大小相等的独立区域,跟踪每个区域里垃

圾的价值,维护一个优先列表,优先回收价值最大的。

区域空间对象的引用使用Remembered Set记录,如果引用的

对象处于不同的区域,通过Card Table把引用信息记录到被引

用对象的Remembered Set中。

过程:初始标记,并发标记,最终标记,筛选回收

9.GC日志

[DefNew:3324k -> 1527k (3712k) ,0.025secs] 3324k→152k(11904k) 0.03 secs

DefNew表示GC发生的区域,区域名字与使用的收集器有关

中括号内部3324k→1527k(3712k)

GC前该区域已使用—>GC后已使用(该区域总容量)

中括号外表示堆信息

secs表示GC花费时间

10.内存分配

10.1优先在Eden分配,如果Eden空间不足,会发生一次MinorGC

(新生代GC),GC时如果所剩空间不足以存放新对象,Survivor 空间又无法存入原有存活对象,那么会将原有对象移入老年代,新对象分配在Eden区

10.2 Serival和ParNew收集器可以通过设置来保证打对象直接进

入老年代

10.3长期存活的对象进入老年代,MinorGC时如果有存活对象能

被Survivor容纳,那么年龄为1,每熬过一次MinorGC年龄加1,默认15岁会晋升到老年代

-XX:MaxTenuringThreshold 设置晋升年龄

10.4 如果Survivor空间中相同年龄的所有对象大小的总和大于

Survivor空间的一半,年龄大于或者等于该年龄的对象就可以直接进入老年代。

10.5 空间分配担保,老年代的连续空间大于新生代的对象总大小,

或者两次晋升的平均大小,就会进行MinorGC,否则将进行FULLGC。

11.Class类文件的结构

8位字节为基础单位的二进制流文件

8位字节以上的数据项,按照高位在前的方式存储

主要组成部分:无符号数和表

11.1 无符号数

u1,u2,u4,u8 代表1字节,2字节,4字节和8字节

可以描述数字,索引引用,数量值,按照UTF-8构成的字符串值。

11.2 表

由多个无符号数或者其他表构成的复合数据类型,

以_info结尾

11.3 Class文件内容顺序

1-4字节,魔数,0xCAFEBABE

5-6字节,次版本号

7-8字节,主版本号

常量池

访问标志

类索引

父类索引

接口索引

字段表集合

方法表集合

属性表集合

常量池:

Class文件中第一个表类型的数据,0x0016 =22 代表21项常量,

索引为1-21,第0项表示“不引用任何一个常量池项目”

池中两大类常量:字面量和符号引用

字面量:文本字符串,声明为final的常量。

符号引用:

1.类和接口的全限定名

2.字段名称和描述符

3.方法名称和描述符

访问标志:

两个字节,类或者接口的访问信息,包括是类还是接口,是否是public,是否是abstract,是否是final(类)

类索引:

类的全限定名,u2

父类索引:

父类的全限定名,单根继承,所以只有一个,除了Object之外,其他父类索引都不为0,u2

接口索引:

u2类型集合,实现了哪些接口,顺序是implements关键字后从左至右

字段表集合:

类级变量(static)以及实例变量,不包括局部变量

方法表集合:

类中的方法

属性表集合:

描述某些专有信息,如方法的代码

12.类的生命周期

加载,验证,准备,解析,初始化,使用,卸载

验证,准备,解析统称为连接

12.1 五种初始化情况

12.1.1:使用new,读取或者设置一个类的静态字段,调用一

个类的静态方法。被final修饰,编译器把结果放入常量池的

静态字段除外。

12.1.2:对类进行反射调用的时候。

12.1.3:初始化一个类的时候,如果父类还没有初始化,先初

始化父类。

12.1.4:初始化main方法的类。

12.1.5:https://www.wendangku.net/doc/373491533.html,ng.invoke.MethodHandle实例,解析结果为

REF_getStatic,REF_putStatic,REF_invokeStatic的方法句柄

12.2 加载

加载过程要完成3件事

12.2.1:获取此类的二进制字节流

12.2.2:将字节流转化为方法区的运行时数据结构

12.2.3:在内存中生成一个对应的Class对象,作为方法区各种

数据的访问入口

12.3 验证

确保字节流符合要求,并且不会危害虚拟机安全,4个阶段

文件格式验证,元数据验证,字节码验证,符号引用验证12.4 准备

为类变量(static)分配内存并设置初始值

12.5 解析

将常量池内的符号引用替换为直接引用

12.6初始化

执行类构造器的方法的过程

clinit方法:由类中的所有类变量(static)的赋值动作和静态

语句块合并产生。

静态语句块可为语句块之后的变量赋值,但不能访问。

虚拟机保证在子类的clinit方法执行之前,父类的clinit方法已

经执行完毕,所以第一个被执行的clinit方法肯定是

https://www.wendangku.net/doc/373491533.html,ng.Object。

父类的静态语句块优先于子类的变量赋值操作。

没有静态语句块也没有变量赋值操作,则不会生成clinit方法。

执行接口的clinit方法不需要执行父接口的clinit方法。

只有一个线程会执行到类的clinit方法。

13.类加载器

即使两个类来源于同一个class文件,被同一个虚拟机加载,只要他们的类加载器不同,那这两个类必定不相等。

13.1 三种系统提供的类加载器

启动类加载器:加载存放在JAVA_HOME\lib目录中的,仅按照

文件名识别,如rt.jar。

扩展类加载器:加载JAVA_HOME\lib\ext目录中的。

应用程序类加载器:加载用户类路径(classpath)上指定的类

库,如果没有自定义的加载器,则这个为默认。

13.2 双亲委派模型

图为双亲委派模型,除了顶层的启动类加载器外,其余的加载

器都应当有自己的父类加载器,父子关系使用组合关系,复用

父加载器的代码。

工作过程:如果要加载一个类,把这个请求委派给父类加载器,每一个都如此,所以最终都是由顶层启动类加载器加载,如果

无法加载,则由自己去加载。

如Object类,所有加载器都要加载,会委派给顶层去加载,

所以Object类在环境中都是同一个。

14.运行时栈帧的结构

每一个方法从调用开始至执行完成都一应着一个栈帧在虚拟

机栈中入栈到出站的过程。

栈帧包括:局部变量表,操作数栈,动态连接,方法返回地址

和附加信息。

位于栈顶的栈帧才是有效的,与这个栈帧相关联的方法称为当

前方法。

14.1局部变量表

用于存放方法参数,方法内部的局部变量。以Slot为单位,

一个Slot可以存放32位以内的数据类型,long和double

用两个Slot来存储。

变量表索引从0开始,如果执行的是非static方法,第0

位索引表示方法所属对象的实例引用,即this关键字,从

1开始按参数顺序占用Slot,在根据方法体内部定义的变量

顺序分配其余的Slot。

14.2操作数栈

后入先出的栈

方法刚开始执行的时候,这个操作数栈是空的,执行过程

中会发生出栈,入栈的操作。

14.3 动态连接

每个栈帧都包含一个指向运行时常量池中该栈帧所属方法

的引用,一部分符号引用会在运行期间转换为直接引用,

成为动态连接。

14.4 方法的返回地址

两种方式退出方法

14.4.1遇到方法返回的字节码指令,为正常出口

14.4.2 遇到了异常,并且在异常表中没有匹配的异常处理

器(异常未被处理),称为异常出口,不会产生任何返回值。

方法正常退出时,调用者的PC计数器的值作为返回地址

异常退出时,通过异常处理器表来确定返回地址

退出方法执行的操作:恢复上层方法的局部变量表和操作

数栈,把返回值(如果有)压入调用者的操作数栈,调整

PC计数器的值,指向后一条指令(字节码)

15.方法调用

唯一任务,确定要调用哪一个方法。

解析:在类加载的解析阶段,会将一部分符号引用转化为直接

引用。条件为:编译器可知,运行期不可变。

例如:静态方法,私有方法,实例构造器,父类方法,final

方法。

16.分派

16.1 静态分派

Human man = new Man();

Human 称为变量的静态类型,Man为变量的实际类型。

静态分派的典型应用是方法重载,重载是根据参数的静态类型

作为判定依据。

16.2 动态分派

主要体现在重写上,根据变量的实际类型来确定。

静态分派属于多分派类型,动态分派属于单分派类型。

17.虚方法表

在方法区中建立一个虚方法表,在连接阶段进行初始化,用于存放方法的实际入口。如果方法的在子类没有被重写,那么地址入口与父类一致,如果重写了,则指向子类实现的入口地址。

18.Java内存模型(JMM)

定义程序中各个变量的访问规则,实例字段,静态字段,构成数组对象的元素。

不包括局部变量和方法参数,因为是线程私有。

所有变量存储在主内存,对应Java堆中的实例数据部分,每条线程有自己的工作内存,对应着虚拟机栈中的部分区域。

工作内存中保存了该线程使用到的变量(主内存的副本拷贝),对变量的所有操作都在工作内存中进行,工作内存中变量只对该线程可见,线程间变量值的传递通过主内存完成。

19.内存间的交互

8种操作

lock:将主内存变量标识为一条线程占用,即上锁。

unlock:将主内存lock状态的变量释放,其他线程可锁定,即

解锁。

read:将主内存变量的值传送到工作内存中,为load准备。

load:将read获取到的值放入工作内存的变量副本。

use:将工作内存中的变量值传递给执行引擎。

assign:将执行引擎接收到的值赋值给工作内存的变量。

store:将工作内存的变量值传递到主内存,为write准备。

write:将store获取到的值放入主内存。

20.volatile变量

作用:

JVM原理以及JVM内存管理机制

一、 JVM简介 JVM是Java Virtual Machine(Java虚拟机)的缩写,JVM是一种用于计算设备的规范,它是一个虚构出来的计算机,是通过在实际的计算机上仿真模拟各种计算机功能来实现的。JVM工作原理和特点主要是指操作系统装入JVM是通过jdk中Java.exe来完成, 首先来说一下JVM工作原理中的jdk这个东西, .JVM 在整个jdk中处于最底层,负责于操作系统的交互,用来屏蔽操作系统环境,提供一个完整的Java运行环境,因此也就虚拟计算机. 操作系统装入JVM是通过jdk中Java.exe来完成。 通过下面4步来完成JVM环境. 1.创建JVM装载环境和配置 2.装载JVM.dll 3.初始化JVM.dll并挂界到JNIENV(JNI调用接口)实例 4.调用JNIEnv实例装载并处理class类。 对于JVM自身的物理结构,我们可以从下图了解:

JVM的一个重要的特征就是它的自动内存管理机制,在执行一段Java代码的时候,会把它所管理的内存划分 成几个不同的数据区域,其中包括: 1. 程序计数器,众所周知,JVM的多线程是通过线程轮流切换并 分配CPU执行时间的方式来实现的,那么每一个线程在切换 后都必须记住它所执行的字节码的行号,以便线程在得到CPU 时间时进行恢复,这个计数器用于记录正在执行的字节码指令的地址,这里要强调的是“字节码”,如果执行的是Native方法,那么这个计数器应该为null; 2.

3. Java计算栈,可以说整个Java程序的执行就是一个出栈入栈 的过程,JVM会为每一个线程创建一个计算栈,用于记录线程中方法的调用和变量的创建,由于在计算栈里分配的内存出栈后立即被抛弃,因此在计算栈里不存在垃圾回收,如果线程请求的栈深度大于JVM允许的深度,会抛出StackOverflowError 异常,在内存耗尽时会抛出OutOfMemoryError异常; 4. Native方法栈,JVM在调用操作系统本地方法的时候会使用到 这个栈; 5. Java堆,由于每个线程分配到的计算栈容量有限,对于可能会 占据大量内存的对象,则会被分配到Java堆中,在栈中包含了指向该对象内存的地址;对于一个Java程序来说,只有一个Java堆,也就是说,所有线程共享一个堆中的对象;由于Java堆不受线程的控制,如果在一个方法结束之后立即回收这个方法使用到的对象,并不能保证其他线程是否正在使用该对象;因此堆中对象的回收由JVM的垃圾收集器统一管理,和某一个线程无关;在HotSpot虚拟机中Java堆被划分为三代:o新生代,正常情况下新创建的对象会被分配到新生代,但如果对象占据的内存足够大以致超过了新生代的容量限 制,也可能被分配到老年代;新生代对象的一个特点是最 新、且生命周期不长,被回收的可能性高;

Java虚拟机(JVM)参数配置说明

Java虚拟机(JVM)参数配置说明 在Java、J2EE大型应用中,JVM非标准参数的配置直接关系到整个系统的性能。 JVM非标准参数指的是JVM底层的一些配置参数,这些参数在一般开发中默认即可,不需要任何配置。但是在生产环境中,为了提高性能,往往需要调整这些参数,以求系统达到最佳新能。另外这些参数的配置也是影响系统稳定性的一个重要因素,相信大多数Java开发人员都见过“O utOfMem ory”类型的错误。呵呵,这其中很可能就是JVM参数配置不当或者就没有配置没意识到配置引起的。 为了说明这些参数,还需要说说JDK中的命令行工具一些知识做铺垫。 首先看如何获取这些命令配置信息说明: 假设你是windows平台,你安装了J2SDK,那么现在你从cmd控制台窗口进入J2SDK安装目录下的bin目录,然后运行java命令,出现如下结果,这些就是包括java.exe工具的和J VM的所有命令都在里面。 ----------------------------------------------------------------------- D:\j2sdk15\bin>java Usage: java [-options] class [args...] (to execute a class) or java [-options] -jar jarfile [args...] (to execute a jar file) where options include: -client to select the "client" VM -server to select the "server" VM -hotspot is a synonym for the "client" VM [deprecated] The default VM is client.

Java虚拟机工作原理(JVM)

As the Java V irtual Machine is a stack-based machine, almost all of its instructions involve the operand stack in some way. Most instructions push values, pop values, or both as they perform their functions. Java虚拟机是基于栈的(stack-based machine)。几乎所有的java虚拟机的指令,都与操作数栈(operand stack)有关.绝大多数指令都会在执行自己功能的时候进行入栈、出栈操作。 1Java体系结构介绍 Javaís architecture arises out of four distinct but interrelated technologies, each of which is defined by a separate specification from Sun Microsystems: 1.1 Java体系结构包括哪几部分? Java体系结构包括4个独立但相关的技术 the Java programming language →程序设计语言 the Java class file format →字节码文件格式 the Java Application Programming Interface→应用编程接口 the Java V irtual Machine →虚拟机 1.2 什么是JVM java虚拟机和java API组成了java运行时。 1.3 JVM的主要任务。 Java虚拟机的主要任务是装载class文件并执行其中的字节码。 Java虚拟机包含了一个类装载器。 类装载器的体系结构 二种类装载器 启动类装载器 用户定义的类装载器 启动类装载器是JVM实现的一部分 当被装载的类引用另外一个类时,JVM就是使用装载第一个类的类装载器装载被引用的类。 1.4 为什么java容易被反编译? ●因为java程序是动态连接的。从一个类到另一个类的引用是符号化的。在静态连接的 可执行程序中。类之间的引用只是直接的指针或者偏移量。相反在java的class文件中,指向另一个类的引用通过字符串清楚的标明了所指向的这个类的名字。

java虚拟机详解 免费

深入理解JVM 1 Java技术与Java虚拟机 说起Java,人们首先想到的是Java编程语言,然而事实上,Java是一种技术,它由四方面组成: Java编程语言、Java类文件格式、Java虚拟机和Java应用程序接口(Java API)。它们的关系如下图所示: 图1 Java四个方面的关系 运行期环境代表着Java平台,开发人员编写Java代码(.java文件),然后将之编译成字节码(.class文件)。最后字节码被装入内存,一旦字节码进入虚拟机,它就会被解释器解释执行,或者是被即时代码发生器有选择的转换成机器码执行。从上图也可以看出Java平台由Java虚拟机和Java应用程序接口搭建,Java 语言则是进入这个平台的通道,用Java语言编写并编译的程序可以运行在这个平台上。这个平台的结构如下图所示:

在Java平台的结构中, 可以看出,Java虚拟机(JVM) 处在核心的位置,是程序与底层操作系统和硬件无关的关键。它的下方是移植接口,移植接口由两部分组成:适配器和Java操作系统, 其中依赖于平台的部分称为适配器;JVM 通过移植接口在具体的平台和操作系统上实现;在JVM 的上方是Java的基本类库和扩展类库以及它们的API,利用Java API编写的应用程序(application) 和小程序(Java applet) 可以在任何Java平台上运行而无需考虑底层平台, 就是因为有Java虚拟机(JVM)实现了程序与操作系统的分离,从而实现了Java 的平台无关性。 那么到底什么是Java虚拟机(JVM)呢?通常我们谈论JVM时,我们的意思可能是: 1. 对JVM规范的的比较抽象的说明; 2. 对JVM的具体实现; 3. 在程序运行期间所生成的一个JVM实例。 对JVM规范的的抽象说明是一些概念的集合,它们已经在书《The Java Virtual Machine Specification》(《Java虚拟机规范》)中被详细地描述了;对JVM的具体实现要么是软件,要么是软件和硬件的组合,它已经被许多生产厂商所实现,并存在于多种平台之上;运行Java程序的任务由JVM的运行期实例单个承担。在本文中我们所讨论的Java虚拟机(JVM)主要针对第三种情况而言。它可以被看成一个想象中的机器,在实际的计算机上通过软件模拟来实现,有自己想象中的硬件,如处理器、堆栈、寄存器等,还有自己相应的指令系统。 JVM在它的生存周期中有一个明确的任务,那就是运行Java程序,因此当Java程序启动的时候,就产生JVM的一个实例;当程序运行结束的时候,该实例也跟着消失了。下面我们从JVM的体系结构和它的运行过程这两个方面来对它进行比较深入的研究。 2 Java虚拟机的体系结构 刚才已经提到,JVM可以由不同的厂商来实现。由于厂商的不同必然导致JVM在实现上的一些不同,然而JVM还是可以实现跨平台的特性,这就要归功于设计JVM时的体系结构了。 我们知道,一个JVM实例的行为不光是它自己的事,还涉及到它的子系统、存储区域、数据类型和指令这些部分,它们描述了JVM的一个抽象的内部体系结构,其目的不光规定实现JVM时它内部的体系结构,更重要的是提供了一种方式,用于严格定义实现时的外部行为。每个JVM都有两种机制,一个是装载具有合适名称的类(类或是接口),叫做类装载子系统;另外的一个负责执行包含在已装载的类或接口中的指令,叫做运行引擎。每个JVM又包括方法区、堆、Java栈、程序计数器和本地方法栈这五个部分,这几个部分和类装载机制与运行引擎机制一起组成的体系结构图为:

Elasticsearch Java虚拟机配置详解

JVM参数Elasticsearch默认值Environment变量 -Xms 256m ES_MIN_MEM -Xmx 1g ES_MAX_MEM -Xms and -Xmx ES_HEAP_SIZE -Xmn ES_HEAP_NEWSIZE -XX:MaxDirectMemorySize ES_DIRECT_SIZE -Xss 256k -XX:UseParNewGC + -XX:UseConcMarkSweepGC + -XX:CMSInitiatingOccupancyFraction 75 -XX:UseCMSInitiatingOccupancyOnly + -XX:UseCondCardMark (commented out) 首先你注意到的是,Elasticsearch预留了256M到1GB的堆内存。 这个设置适用于开发和演示环境。开发人员只需要简单的解压发行包,再执 行./bin/elasticsearch -f就完成了Elasticsearch的安装。当然这点对于开发来说非常棒,并且在很多场景下都能工作,但是当你需要更多内存来降低Elasticsearch负载的时候就不行了,你需要比2GB RAM更多的可用内存。

ES_MIN_MEM/ES_MAX_MEM是控制堆大小的配置。新的ES_HEAP_SIZE变量是一个更为便利的选择,因为将堆的初始大小和最大值设为相同。也推荐在分配堆内存时尽可能不要用内存的碎片。内存碎片对于性能优化来说非常不利。 ES_HEAP_NEWSIZE是可选参数,它控制堆的子集大小,也就是新生代的大小。 ES_DIRECT_SIZE控制本机直接内存大小,即JVM管理NIO框架中使用的数据区域大小。本机直接内存可以被映射到虚拟地址空间上,这样在64位的机器上更高效,因为可以规避文件系统缓冲。Elasticsearch对本机直接内存没有限制(可能导致OOM)。 由于历史原因Java虚拟机有多个垃圾收集器。可以通过以下的JVM参数组合启用: JVM parameter Garbage collector -XX:+UseSerialGC serial collector -XX:+UseParallelGC parallel collector -XX:+UseParallelOldGC Parallel compacting collector -XX:+UseConcMarkSweepGC Concurrent-Mark-Sweep (CMS) collector -XX:+UseG1GC Garbage-First collector (G1) UseParNewGC和UseConcMarkSweepGC组合启用垃圾收集器的并发多线程模式。UseConcMarkSweepGC自动选择UseParNewGC模式并禁用串行收集器(Serial collector)。在Java6中这是默认行为。 CMSInitiatingOccupancyFraction提炼了一种CMS(Concurrent-Mark-Sweep)垃圾收集设置;它将旧生代触发垃圾收集的阀值设为75.旧生代的大小是堆大小减去新生代大小。这告诉JVM当堆内容达到75%时启用垃圾收集。这是个估计的值,因为越小的堆可能需要越早启动GC。 UseCondCardMark将在垃圾收集器的card table使用时,在marking之前进行额外的判断,避免冗余的store操作。UseCondCardMark不影响Garbage-First收集器。强烈推荐在高并发场景下配置这个参数(规避card table marking技术在高并发场景下的降低吞吐量的负面作用)。在ElasticSearch中,这个参数是被注释掉的。 有些配置可以参考诸如Apache Cassandra项目,他们在JVM上有类似的需求。 总而言之,ElastciSearch配置上推荐: 1. 不采用自动的堆内存配置,将堆大小默认最大值设为1GB 2.调整触发垃圾收集的阀值,比如将gc设为75%堆大小的时候触发,这样不会影响性能。 3.禁用Java7默认的G1收集器,前提是你的ElasticSearch跑在Java7u4以上的版本上。JVM进程的内存结果 JVM内存由几部分组成: Java代码本身:包括内部代码、数据、接口,调试和监控代理或者字节码指令 非堆内存:用于加载类 栈内存:用于为每个线程存储本地变量和操作数

深入理解Java虚拟机笔记(带目录)

目录 1.虚拟机内存结构 (1) 2.对象在内存中的布局 (3) 3.判断对象是否死亡 (4) 4.引用的4中情况 (4) 5.垃圾收集算法 (5) 6.HotSpot虚拟机算法实现 (6) 7.如何在GC发生时让所有线程都要附近的安全点停下 (6) 8.垃圾收集器 (7) 9.GC日志 (9) 10.内存分配 (10) 11.Class类文件的结构 (10) 12.类的生命周期 (13) 13.类加载器 (15) 14.运行时栈帧的结构 (16) 15. 方法调用 (18) 16. 分派 (19) 17.虚方法表 (19) 18.Java内存模型(JMM) (19) 19.内存间的交互 (20) 20.volatile变量 (20) 21.原子性 (21) 22.可见性 (22) 23.有序性 (22) 24.先行发生原则 (22) 25.Java线程调度 (23) 26.线程的状态 (24) 27.线程安全 (25) 28.线程安全的实现方法 (26) 29.锁优化 (27) 30.编译优化技术 (29) 1.虚拟机内存结构 线程私有:虚拟机栈,本地方法栈,程序计数器 线程共享:堆,方法区(包括运行时常量池)

1.1程序计数器 当前程序锁执行的字节码行号指示器,记录下一条需要执行的 指令。 1.2虚拟机栈 生命周期与线程相同,每个方法在执行时都会创建一个栈帧。 方法执行的过程,就是栈帧入栈到出栈的过程。 栈帧用于存放局部变量表,操作数栈,动态链接,方法出口等 信息。 局部变量表存放了编译期可知的基本数据类型和对象引用。1.3 本地方法栈 为虚拟机使用到的Native方法服务。 目前HotSpot虚拟机将本地方法栈和虚拟机栈合二为一。 1.4堆 存放对象实例,所有线程共享。 1.5 方法区(永久代) 存放被虚拟机加载的类信息,常量,静态变量,即时编译器编 译后的代码等。

深入理解java虚拟机

深入理解java虚拟机 (一)虚拟机内存划分 Java虚拟机在执行Java程序时,会把它管理的内存划分为若干个不同的数据区。这些区域有不同的特性,起不同的作用。它们有各自的创建时间,销毁时间。有的区域随着进程的启动而创建,随着进程结束而销毁,有的则始终贯穿虚拟机整个生命周期。 Java虚拟机运行时内存区域主要分为七部分,分别是:程序计数器,Java虚拟机栈,本地方法栈,方法区,Java堆,运行时常量池,直接内存。 如上图所示(图片来源于网络): 蓝色区域包裹的部分为运行时几个数据区域: 白色的部分为线程私有的,既随着线程的启动而创建。每个线程都拥有各自的一份内存区域。它们是:JAVA栈(JAVA STACK),本地方法栈(NATIVE METHOD STACK),和程序计数器(PROGRAM COUNTER REGISTER)。 黄色部分是线程共享的,所有的线程共享该区域的内容。他们是: 方法区(METHOD AREA),堆(HEAP)。 我们分别来介绍这些区域。 (1)程序计数器(program counter register)

学过计算机组成原理的都知道计算机处理器中的程序计数器。当处理器执行一条指令时,首先需要根据PC中存放的指令地址,将指令由内存取到指令寄存器中,此过程称为“取指令”。与此同时,PC中的地址或自动加1或由转移指针给出下一条指令的地址。此后经过分析指令,执行指令。完成第一条指令的执行,而后根据PC取出第二条指令的地址,如此循环,执行每一条指令。 处理器的程序计数器是指寄存器,而java程序计数器是指一小块内存空间。java代码编译字节码之后,虚拟机会一行一行的解释字节码,并翻印成本地代码。这个程序计数器盛放的就是当前线程所执行字节码的行号的指示器。在虚拟机概念模型中,字节码解释器工作室就是通过改变这个计数器的值来选取下一条需要执行的字节码指令,分支,循环,跳转,异常处理等都依赖于它。 Java虚拟机的多线程是通过线程轮流切换并分配处理器执行时间的方式实现的,因此为了线程切换后还能恢复执行位置,每条线程都需要一个独立的程序计数器。 如果线程正在执行的是一个Java方法,这个计数器记录的是正在执行的虚拟机字节码指令的地址;如果执行的是Java Native方法,这个计数器值为空。 而且程序计数器是Java虚拟机中没有规定任何OutOfMemoryError的区域。 (2)虚拟机栈 Java虚拟机栈(VM Stack)也是线程私有的,因此它的生命周期也和线程相同。它存放的是Java方法执行时的数据,既描述的是Java方法执行的内存模型:每个方法开始执行的时候,都会创建一个栈帧(Stack Frame)用于储存局部变量表、栈操作数、动态链接、方法出口等信息。每个方法从调用到执行完成就对应一个栈帧在虚拟机栈中入栈到出栈的过程。经常有人把Java内存分为堆内存和栈内存,这种是比较粗糙的分法,很大原因是大多数程序‘猿’最关注的,与对象内存分配最密切的区域就是堆和栈。局部变量表存放的是编译器可知的各种基本数据类型(boolean 、byte、int、long、char、short、float、double)、对象引用(reference类型)和returnAddress类型(它指向了一条字节码指令的地址)。其中64bit长度的long和double会占用两个局部变量空间(Slot),其余的数据类型只占用一个。局部变量表所需的内存空间是在编译时期确定的,在方法运行期间不会改变局部变量表的大小。在Java虚拟机规范中,对这部分区域规定了两种异常:1、当一个线程的栈深度大于虚拟机所允许的深度的时候,将会抛出StackOverflowError异常; 2、如果当创建一个新的线程时无法申请到足够的内存,则会抛出OutOfMemeryError异常。 (3)本地方法栈 本地方法栈(Native Method Stack)与虚拟机栈所发挥的作用是十分相似的,他们之间的区别不过是虚拟机栈为Java方法字节码服务,而本地方法栈则为Native方法服务。在虚拟机规范中对本地方法使用的语言和使用方法与数据结构没有强制规定,因此具体的虚拟机可

Java虚拟机的内存结构

我们都知道虚拟机的内存划分了多个区域,并不是一张大饼。那么为什么要划分为多块区域呢,直接搞一块区域,所有用到内存的地方都往这块区域里扔不就行了,岂不痛快。是的,如果不进行区域划分,扔的时候确实痛快,可用的时候再去找怎么办呢,这就引入了第一个问题,分类管理,类似于衣柜,系统磁盘等等,为了方便查找,我们会进行分区分类。另外如果不进行分区,内存用尽了怎么办呢?这里就引入了内存划分的第二个原因,就是为了方便内存的回收。如果不分,回收内存需要全部内存扫描,那就慢死了,内存根据不同的使用功能分成不同的区域,那么内存回收也就可以根据每个区域的特定进行回收,比如像栈内存中的栈帧,随着方法的执行栈帧进栈,方法执行完毕就出栈了,而对于像堆内存的回收就需要使用经典的回收算法来进行回收了,所以看起来分类这么麻烦,其实是大有好处的。 提到虚拟机的内存结构,可能首先想起来的就是堆栈。对象分配到堆上,栈上用来分配对象的引用以及一些基本数据类型相关的值。但是·虚拟机的内存结构远比此要复杂的多。除了我们所认识的(还没有认识完全)的堆栈以外,还有程序计数器,本地方法栈和方法区。我们平时所说的栈内存,一般是指的栈内存中的局部变量表。下面是官方所给的虚拟机的内存结构图

从图中可以看到有5大内存区域,按照是否被线程所共享可分为两部分,一部分是线程独占区域,包括Java栈,本地方法栈和程序计数器。还有一部分是被线程所共享的,包括方法区和堆。什么是线程共享和线程独占呢,非常好理解,我们知道每一个Java进行都会有多个线程同时运行,那么线程共享区的这片区域就是被所有线程一起使用的,不管有多少个线程,这片空间始终就这一个。而线程的独占区,是每个线程都有这么一份内存空间,每个线程的这片空间都是独有的,有多少个线程就有多少个这么个空间。上图的区域的大小并不代表实际内存区域的大小,实际运行过程中,内存区域的大小也是可以动态调整的。下面来具体说说每一个区域的主要功能。

JVM详解

JVM详解 本文详细讲解了JVM(Java Virtual Machine)的方方面面,首先由java的特性来描绘JVM 的大致应用,再细细阐述了JVM的原理及内存管理机制和调优.最后讲述了与JVM密切相关的Java GC机制. 本文内容大多来自网络,但内容十分丰富,是学习JVM的好资料. 后面会再针对JVM的两大职责class loader和execution engine进行讲解 若有疑问 目录 Java相关 (2) 1.1Java定义 (2) 1.2Java的开发流程 (2) 1.3Java运行的原理 (3) 1.4半编译半解释 (4) 1.5平台无关性 (5) JVM内存模型 (5) 2.1JVM规范 (6) 2.2 Sun JVM (9) 2.3 SUN JVM内存管理(优化) (10) 2.4 SUN JVM调优 (13) 2.5.JVM简单理解 (16) 2.5.1Java栈 (16) 2.5.2堆 (16) 2.5.3堆栈分离的好处 (19) 2.5.4 堆(heap)和栈(stack) (19) JAVA垃圾收集器 (20) 3.1垃圾收集简史 (20) 3.2常见的垃圾收集策略 (20) 3.2.1Reference Counting(引用计数) (20) 3.2.2跟踪收集器 (21) 3.3JVM的垃圾收集策略 (25) 3.3.1Serial Collector (25) 3.3.2 Parallel Collector (25) 3.3.3 Concurrent Collector (26) Java虚拟机(JVM)参数配置说明 (26)

JAVA虚拟机性能参数调优指导书

Java虚拟机性能参数调优指导书 (仅供内部使用)

目录 1概述 (5) 2JAVA虚拟机运行机制概览 (5) 2.1运行时分析 (5) 2.2垃圾收集和线程同步 (7) 3JAVA虚拟机参数分类说明 (8) 3.1Java虚拟机标准参数 (8) 3.2Java虚拟机扩展参数 (10) 4JAVA应用性能测试调优经验总结 (13) 4.1GC调优参数的使用 (13) 4.2JIT调优参数的使用 (14) 4.3Java线程调优参数的使用 (14) 5结束语 (15) 6参考文献 (15)

表目录 表1 JVM 标准参数集 (10) 表2 JVM 扩展参数集 (10) 表3 JVM GC/Hotspot相关参数集 (12) 表4 JVM 性能统计参数集 (13)

错误!未找到引用源。 关键词:Java、垃圾收集、虚拟机、即时编译 摘要:随着JAVA在应用系统级的项目开发中的使用越来越广泛,虚拟机、垃圾收集、热点编译、J2EE等新技术层出不穷,JAVA作为系统级开发的一个选择的优势也越来越明显,在此同时 其不能完全编译、垃圾收集等与生俱有的特征也使得JAVA备受争议的“慢”得到更多的关 注。本文通过对JAVA虚拟机的运行机理的分析,以及JAVA虚拟机参数使用说明等描述,试 图使读者能够更好的运行他的基于JAVA的应用系统,以最小的代价换取最大的收益。 缩略语清单: 缩略语英文全名中文解释 JAVA SUN公司发明的一种语言 JVM Java Virtual Machine JAVA虚拟机 GC Garbage Collection 垃圾收集 HotSpot Java虚拟机内部的一种热点编译技术 JIT Just-In-Time 即时编译技术

java实验报告实验1答案

实验一熟悉NetBeans IDE 平台,开发环境及Java编程 实验目的: 1、我们使用的开发平台是NetBeans IDE,希望通过本次实验同学们能对NetBeans IDE 的开发环境有一个清楚的了解并能熟练运用,对Java语法进行初步运用,对面向对象的编程有一个直观的认识和深入理解,对于Java的基础知识进行理解运用和巩固。为以后的实验中能够进行开发程序打下基础。 2、通过编程和上机实验理解Java语言是如何体现面向对象编程基本思想,了解类的封装方法,以及如何创建类和对象,了解成员变量和成员方法的特性,掌握OOP方式进行程序设计的方法,了解类的继承性和多态性的作用。 实验内容: ● 1. 编写一个体现面向对象思想的程序。 ● 2. 编写一个创建对象和使用对象的方法的程序。 ● 3. 编写一个显示当前日期和时间的程序。 ● 4. 编写不同成员变量修饰方法的程序。 ● 5. 编写不同成员方法修饰方法的程序。 ● 6. 编写体现类的继承性(成员变量、成员方法、成员变量隐藏)的程序。 ●7. 编写体现类的多态性(成员方法重载、构造方法重载)的程序。 实验步骤: ●双击桌面上的NetBeans IDE 6.5.1快捷方式或在文件菜单中打开它。 图1-1 点击文件,创建新项目,创建一个项目名:experiment1。

点击按钮下一步: 在项目名称处输入:experiment1 然后点击完成:

在experiment1 下实现 程序 项目experiment1

样例1:编写应用程序输出如下三角形。 * *** ***** ******* 【参考程序】 public class Star { public static void main(String a[]) { System.out.println(" *"); System.out.println(" ***"); System.out.println(" *****"); System.out.println("*******"); } } 程序运行结果如图1-2所示。 【编程技巧】 (1) main方法是应用程序执行入口; (2) 如何在命令控制台输出字符串。 (3) 输出杨辉三角的前10行;进一步用参数传递的方式输出,例如,shuchu(n)表示 输出杨辉三角的前n行。 样例2:编写Applet程序绘制一个红色三角形,三角形中央绘制兰色文字“三角形”。 【参考程序】

深入理解Java反射机制汇总

深入理解Java反射机制 本文较为详细的分析了Java反射机制。分享给大家供大家参考,具体如下: 一、预先需要掌握的知识(java虚拟机) java虚拟机的方法区: java虚拟机有一个运行时数据区,这个数据区又被分为方法区,堆区和栈区,我们这里需要了解的主要是方法区。方法区的主要作用是存储被装载的类的类型信息,当java虚拟机装载某个类型的时候,需要类装载器定位相应的class文件,然后将其读入到java虚拟机中,紧接着虚拟机提取class 中的类型信息,将这些信息存储到方法区中。这些信息主要包括: 1、这个类型的全限定名 2、这个类型的直接超类的全限定名 3、这个类型是类类型还是接口类型 4、这个类型的访问修饰符 5、任何直接超接口的全限定名的有序列表 6、该类型的常量池 7、字段信息 8、方法信息 9、除了常量以外的所有类变量 10、一个到class类的引用 等等(读者可以参考《深入java虚拟机》这本书的叙述) Class类: Class类是一个非常重要的java基础类,每当装载一个新的类型的时候,java虚拟机都会在java堆中创建一个对应于新类型的Class实例,该实例就代表此类型,通过该Class实例我们就可以访问该类型的基本信息。上面说到在方法区中会存储某个被装载类的类型信息,我们就可以通过Class实例来访问这些信息。比如,对于上面说到的信息Class中都有对应的方法,如下:

1、getName();这个类型的全限定名 2、getSuperClass();这个类型的直接超类的全限定名 3、isInterface();这个类型是类类型还是接口类型 4、getTypeParamters();这个类型的访问修饰符 5、getInterfaces();任何直接超接口的全限定名的有序列表 6、getFields();字段信息 7、getMethods();方法信息 等等(读者可以自己参看jdk帮助文档,得到更多的信息) 二、java反射详解 反射的概念:所谓的反射就是java语言在运行时拥有一项自观的能力,反射使您的程序代码能够得到装载到JVM中的类的内部信息,允许您执行程序时才得到需要类的内部信息,而不是在编写代码的时候就必须要知道所需类的内部信息,这使反射成为构建灵活的应用的主要工具。 反射的常用类和函数:Java反射机制的实现要借助于4个类:Class,Constructor,Field,Method;其中class代表的是类对象,Constructor-类的构造器对象,Field-类的属性对象,Method -类的方法对象,通过这四个对象我们可以粗略的看到一个类的各个组成部分。其中最核心的就是Class类,它是实现反射的基础,它包含的方法我们在第一部分已经进行了基本的阐述。应用反射时我们最关心的一般是一个类的构造器、属性和方法,下面我们主要介绍Class 类中针对这三个元素的方法: 1、得到构造器的方法 Constructor getConstructor(Class[] params) -- 获得使用特殊的参数类型的公共构造函数,Constructor[] getConstructors() -- 获得类的所有公共构造函数 Constructor getDeclaredConstructor(Class[] params) -- 获得使用特定参数类型的构造函数(与接入级别无关) Constructor[] getDeclaredConstructors() -- 获得类的所有构造函数(与接入级别无关) 2、获得字段信息的方法

Java的类一些常识

Java的类一些常识 “1、请解释Java语言的跨平台特性。 解析:虽然不知道什么是跨平台也可以使用Java语言进行编程,但是对于一个Java编程员来说,理解跨平台特性能够更深入掌握Java语言,所以企业中往往要求应聘者至少理解这个特性。 参考答案:Java的跨平台特性也被称为可移植性、平台无关性,或者一次编写处处运行。他的意思就是如果用Java语言编写一个应用,那么就可以在不同平台上运行,而不需要为不同平台单独运行开发。之所以能实现跨平台的特性。主要得益于Java虚拟机(JVM),JVM解释器在运行Java应用时根据当前平台进行解释,解释成符合当前平台规范的机器码,所以可以实现同样的应用在不同平台上都能运行。 “2、请列举JAVA语言的主要特点 解析:了解一门语言,往往从熟悉该语言的主要特点开始入手,所以企业也常常通过应聘者对JAVA语言特点的掌握程度而判断其语言基础是否扎实。 参考答案:JAVA语言有很多特点,主要包括:①跨平台性:一个应用可以不经过修改直接运行到不同的平台上。②面向对象:JAVA语言是一门面向对面的语言,可以使用对象的属性和行为,可以使用面向对象的思想进行分析设计,并实现整个应用。③解释执行JAVA应用时,JVM中的解释器将解释类文件,生成符合当前平台的字节码。④自动回收:JAVA 应用中的垃圾回收是自动进行的,JVM中的后台线程将监视内存中数据的使用,当内存中的数据不再被引用时,将被作为垃圾回收,而不需要程序员动手回收。 “3、请说明一个JAVA类中主要包含哪几个元素?并说明每种元素的作用。 解析:无论简单还是复杂的JAVA应用,都是由若干个类组成,所以类是JAVA应用的组成单位。了解一个类中包含的主要元素能够对类有一个清晰的认识。一个类中往往会有五种元素,即属性、方法、构造方法、块以及内部类、其实块和内部类比较少见。 参考答案:JAVA类中主要包含属性、方法、构造方法、块以及内部类。

java虚拟机的原理和作用

Java虚拟机 一、什么是Java虚拟机 Java虚拟机是一个想象中的机器,在实际的计算机上通过软件模拟来实现。Java虚拟机有自己想象中的硬件,如处理器、堆栈、寄存器等,还具有相应的指令系统。 1.为什么要使用Java虚拟机 Java语言的一个非常重要的特点就是与平台的无关性。而使用Java虚拟机是实现这一特点的关键。一般的高级语言如果要在不同的平台上运行,至少需要编译成不同的目标代码。而引入Java语言虚拟机后,Java语言在不同平台上运行时不需要重新编译。Java语言使用模式Java虚拟机屏蔽了与具体平台相关的信息,使得Java语言编译程序只需生成在Java虚拟机上运行的目标代码(字节码),就可以在多种平台上不加修改地运行。Java虚拟机在执行字节码时,把字节码解释成具体平台上的机器指令执行。 2.谁需要了解Java虚拟机 Java虚拟机是Java语言底层实现的基础,对Java语言感兴趣的人都应对Java虚拟机有个大概的了解。这有助于理解Java语言的一些性质,也有助于使用Java语言。对于要在特定平台上实现Java虚拟机的软件人员,Java语言的编译器作者以及要用硬件芯片实现Java虚拟机的人来说,则必须深刻理解Java 虚拟机的规范。另外,如果你想扩展Java语言,或是把其它语言编译成Java语言的字节码,你也需要深入地了解Java虚拟机。 3.Java虚拟机支持的数据类型 Java虚拟机支持Java语言的基本数据类型如下: byte://1字节有符号整数的补码 short://2字节有符号整数的补码 int://4字节有符号整数的补码 long://8字节有符号整数的补码 float://4字节IEEE754单精度浮点数 double://8字节IEEE754双精度浮点数 char://2字节无符号Unicode字符 几乎所有的Java类型检查都是在编译时完成的。上面列出的原始数据类型的数据在Java执行时不需要用硬件标记。*作这些原始数据类型数据的字节码(指令)本身就已经指出了*作数的数据类型,例如iadd、ladd、fadd和dadd指令都是把两个数相加,其*作数类型别是int、long、 float和double。虚拟机没有给boolean(布尔)类型设置单独的指令。boolean型的数据是由integer指令,包括integer 返回来处理的。boolean型的数组则是用byte数组来处理的。虚拟机使用IEEE754格式的浮点数。不支持IEEE格式的较旧的计算机,在运行 Java数值计算程序时,可能会非常慢。 虚拟机支持的其它数据类型包括: object//对一个Javaobject(对象)的4字节引用 returnAddress//4字节,用于jsr/ret/jsr-w/ret-w指令 注:Java数组被当作object处理。 虚拟机的规范对于object内部的结构没有任何特殊的要求。在Sun公司的实现中,对object的引用是一个句柄,其中包含一对指针:一个指针指向该object的方法表,另一个指向该object的数据。用Java

java虚拟机环境配置

文章分类:Java编程 第一步:下载jdk和tomcat:JDK下载Tomcat下载 最新的jdk为1.6.10,tomcat为6.0,建议jdk1.4以上,tomcat4.0以上 第二步:安装和配置你的jdk和tomcat:执行jdk和tomcat的安装程序,然后设置按照路径进行安装即可。 1.安装jdk以后,需要配置一下环境变量,在我的电脑->属性->高级->环境变量->系统变量中添加以下环境变量(假定你的jdk安装在C:\Program Files\Java):JAVA_HOME=C:\Program Files\Java\jdk1.6.0_10 classpath=.;%JAVA_HOME%\lib\dt.jar;%JAVA_HOME%\lib\tools.jar;(.;一定不能少,因为它代表当前路径) path=%JAVA_HOME%\bin 接着可以写一个简单的java程序来测试JDK是否已安装成功: Java代码 1.public class Test{ 2. 3. public static void main(String args[]){ 4. 5. System.out.println("This is a test program."); 6. 7. } 8. 9.} 将上面的这段程序保存为文件名为 Test.java的文件。 然后打开命令提示符窗口,cd到你的Test.java所在目录,然后键入下面的命令javac Test.java java Test 此时如果看到打印出来This is a test program.的话说明安装成功了,如果没有打印出这句话,你需要仔细检查一下你的配置情况。 2.安装Tomcat后,在我的电脑->属性->高级->环境变量->系统变量中添加以下环境变量(假定你的tomcat安装在c:\tomcat): CATALINA_HOME:C:\Program Files\Apache Software Foundation\Tomcat 6.0 CATALINA_BASE:C:\Program Files\Apache Software Foundation\Tomcat 6.0

java中的四个核心概念

Java已经成为一个庞大而复杂的技术平台,对于开发人员而言,要想更好的掌握Java技术,深入理解底层的技术处理细节必不可少。现在介绍下java的四个核心概念: 1.Java虚拟机 Java虚拟机的主要任务是装在class文件并且执行其中的字节码。Java 虚拟机包含一个类装载器,它可以从程序和 API中装载class文件。Java API中只有程序执行时需要的那些类才会被装载。字节码由执行引擎来执行。不同的Java虚拟机中,执行引擎可能实现得非常不同。在由软件实现的虚拟机中,最简单的执行引擎就是一次性解释字节码。 另一种执行引擎更快,但是也更消耗内存,叫做"即时编译器(just-in-time compiler)"。在这种情况下,第一次被执行的字节码会被编译成本地机器代码。编译出的本地机器代码会被缓存,当方法以后被调用的时候可以重用。 第三种执行引擎是自适应优化器。在这种方法里,虚拟机开始的时候解释字节码,但是会监视运行中程序的活动,并且记录下使用最频繁的代码段。程序运行的时候,虚拟机只把那些活动最频繁的代码编译成本地代码,其他的代码由于使用得不是很频繁,继续保留为字节码-由虚拟机继续解释它们。 一个自适应的优化器可以使得Java虚拟机在80%~90%的时间里执行被优化过的本地代码,而只需要编译10%~20%的对性能有影响的代码。 2.类装载器的体系结构 一个Java应用程序可以使用两种类装载器:"启动(bootstrap)"类装载器和用户定义的类装载器。启动类装载器(这是系统中唯一的)是 Java虚拟机实现的一部分。启动类装载器通常使用某种默认方式从本地磁盘中装载类,包括Java API类(启动类装载器也被称为原始类装载器、系统类装载器或者默认类装载器)。Java培训:https://www.wendangku.net/doc/373491533.html, Java应用程序能够在运行时安装用户定义的类装载器,这种类装载器能够使用自定义的方式来装载类。例如,从网络下载class文件。尽管启动类装载器是虚拟机实现的本质部分,而用户定义的类装载器不是,但用户定义的类装载器能够用Java来编写,能够被编译成class文件,能够被虚拟机装载,还能够像其它对象一样实例化。 3.Java class文件 Java class文件主要在平台无关性和网络移动性方面使Java更适合网络。它在平台无关性方面的任务是:为Java程序提供独立于底层主机平台的二进制形式的服务。这种途径途径打破了C或者C++等语言所遵循的传统,使用这些传统语言写的程序通常首先被编译,然后被连接成单

win7下Java虚拟机的配置(图文教程)

win7(windows7)下java环境变量配置方法 2009-10-28 08:30:25 来源:[url=]编程伊甸园[/url] 作者:编程伊甸园 windows7下java环境变量配置方法: 1.用鼠标右击“我的电脑”->属性 600)makesmallpic(this,600,1800);" height=418> 选择左边导航的“高级系统设置”选项,然后这回熟悉了吧?

600)makesmallpic(this,600,1800);" height=441> 继续选择右下角的“环境变量”选项 2.进行win7下Java环境变量配置 600)makesmallpic(this,600,1800);" height=407> 在"系统变量"下进行如下配置: (1)新建->变量名:JAVA_HOME 变量值:D:\Java\jdk1.6.0_12(这只是我的JDK安装路径) (2)编辑->变量名:Path 在变量值的最前面加上:%JAVA_HOME%\bin;%JAVA_HOME%\jre\bin (3)新建->变量名:CLASSPATH 变量值:.;%JAVA_HOME%\lib;%JAVA_HOME%\lib\dt.jar;%JAVA_HOME%\lib\tools.jar (4)编辑->变量名:JAVA_HOME,变量值:D:\Java\jdk1.6.0_10

注意:当设置的变量在末尾时,不要加上“;”。 3.测试下环境变量是否设置成功 在左下角的搜索框中键入 cmd 或者按下“WIN+R”键,“WIN”键就是"CTRL"和“ALT””中间那个微软图标那个键;分别输入java,javac,java -version 命令 如果出现如下信息: 600)makesmallpic(this,600,1800);" height=391>

相关文档
相关文档 最新文档