深入理解JVM
- 格式:doc
- 大小:79.50 KB
- 文档页数:8
深入分析JVM的优点与缺点JVM(Java虚拟机)是一种在计算机上运行Java字节码的虚拟机,它具有许多优点和一些缺点。
本文将深入分析JVM的优势和不足之处,具体如下:优点:1. 跨平台性:JVM是为Java程序设计语言而创建的虚拟机,可以在不同的操作系统上运行Java程序,无需重新编写或修改代码。
这种跨平台性使得Java成为一种非常流行的编程语言。
2.内存管理:JVM提供了自动内存管理,通过垃圾回收器自动处理内存分配和释放,这样程序员就不需要手动管理内存,减轻了开发人员的负担并且避免了常见的内存泄漏和溢出问题。
3.安全性:通过安全沙箱机制,JVM可以在程序执行期间限制程序对底层系统资源的访问。
这样可以防止恶意软件和病毒对计算机的破坏,提高了安全性。
4. 高可移植性:由于JVM的跨平台性,Java程序一旦在一个平台上编写和测试完成,就可以在其他平台上运行,无需重新编写和调试代码。
5. 高性能:尽管Java是解释型语言,但JVM使用即时编译器(JIT)将Java字节码直接编译成机器码,从而提高了程序的执行效率。
JIT编译器可以对热点代码进行优化,提供接近于本地代码执行的性能。
不足之处:1.内存消耗:JVM启动和运行需要占用较大的内存,而且由于垃圾回收机制,JVM的内存占用也较高。
在一些资源有限的环境中,这可能导致问题。
2. 执行速度:虽然JIT编译器可以提高Java程序的执行速度,但与本地代码相比,Java程序的执行速度仍然较慢。
这一点在对实时性要求较高的应用程序中可能会成为问题。
3.配置复杂性:由于JVM的各种配置选项和优化参数较多,使得调优和优化JVM变得复杂。
不正确的配置可能导致性能下降或其他问题。
4.学习成本:相对于其他编程语言和平台,学习和理解JVM的工作原理和内部机制可能需要更多的时间和精力。
5. 移植性限制:尽管JVM使得Java程序具有高度可移植性,但一些情况下,特定平台的限制或特性可能会对Java程序的移植性产生一些限制。
JVM内存设置方法JVM(Java虚拟机)是Java程序的运行环境,它负责执行Java字节码,并管理程序的内存。
在运行Java程序时,合理地设置JVM的内存大小是非常重要的,它会影响程序的性能和稳定性。
下面是一些关于JVM内存设置的方法和注意事项:1. 初始堆大小(-Xms)和最大堆大小(-Xmx):初始堆大小指定了JVM初始时分配的堆内存大小,最大堆大小则指定了堆内存的上限。
可以通过在启动命令中加上-Xms和-Xmx参数来设置堆内存大小,例如:```java -Xms256m -Xmx512m MyApp```这样就设置了初始堆大小为256MB,最大堆大小为512MB。
2.堆内存的大小选择:堆内存的大小应根据应用程序的需求和服务器硬件条件来选择。
如果堆内存过小,可能会导致OutOfMemoryError;如果堆内存过大,可能会导致频繁的垃圾回收,影响程序的性能。
可以通过监控JVM的堆使用情况来判断是否需要调整堆内存的大小。
可以使用JVM自带的JVisualVM工具或第三方的工具如G1GC日志分析工具进行监控。
3.堆内存的分代设置:堆内存分为新生代(Young Generation)、老年代(Old Generation)和永久代(Permanent Generation,JDK8及之前的版本)/元空间(Metaspace,JDK8及之后的版本)。
新生代用于存储新创建的对象,老年代用于存储长时间存活的对象,永久代/元空间用于存储类和方法等信息。
可以通过设置堆内存的分代比例来调整堆内存的大小,例如:```-XX:NewRatio=2```这样就将堆内存的新生代和老年代的大小比例设置为1:2、可以根据应用程序的特点和需求进行调整。
4.非堆内存的设置:非堆内存包括方法区、直接内存等。
可以通过设置参数来调整非堆内存的大小,例如:```-XX:MaxMetaspaceSize=256m```这样就设置了元空间的最大大小为256MB。
jvm 的执行流程JVM的执行流程JVM(Java虚拟机)是Java语言的核心,它负责将Java源代码编译后的字节码文件解释执行。
JVM的执行流程可以分为加载、验证、准备、解析、初始化、使用和卸载等阶段。
1. 加载加载是JVM执行流程的第一步,它负责将字节码文件加载到内存中。
首先,JVM会通过类加载器(ClassLoader)找到并加载字节码文件。
类加载器会根据类的全限定名查找并加载相应的字节码文件。
一旦字节码文件被加载到内存中,JVM会创建一个代表该类的Class对象,并将其存放在方法区中。
2. 验证验证是JVM执行流程中的第二步,它主要负责验证加载的字节码文件的正确性和安全性。
在验证阶段,JVM会对字节码文件进行各种检查,包括文件格式的验证、语义的验证、字节码的验证和符号引用的验证。
通过验证,JVM可以确保加载的字节码文件是合法且安全的,以防止恶意代码对系统造成损害。
3. 准备准备是JVM执行流程的第三步,它主要负责为类的静态变量分配内存并设置初始值。
在准备阶段,JVM会为每个类的静态变量在方法区中分配内存,并根据变量的类型设置初始值。
这些初始值通常是Java语言中的默认值,如0、null、false等。
4. 解析解析是JVM执行流程的第四步,它主要负责将符号引用解析为直接引用。
在解析阶段,JVM会将字节码文件中的符号引用转换为直接引用,以便后续的内存访问操作。
符号引用是一种符号化的引用,它通过名称来标识一个目标,而直接引用则是一个指向目标的具体指针或偏移量。
5. 初始化初始化是JVM执行流程的第五步,它主要负责执行类的初始化代码。
在初始化阶段,JVM会按照程序的顺序执行类的静态代码块和静态变量的赋值语句。
类的初始化是在首次使用该类之前进行的,它保证了类的静态变量在使用之前已经被正确初始化。
6. 使用使用是JVM执行流程的第六步,它主要负责执行程序代码。
在使用阶段,JVM会按照程序的逻辑顺序执行字节码指令,包括方法调用、变量操作、控制流程等。
jvm non heap 默认值Java虚拟机(Java Virtual Machine,简称JVM)是Java平台的核心组件之一,负责执行Java字节码。
JVM管理着Java应用程序的内存,其中包括堆内存(Heap)和非堆内存(Non-Heap)。
本文将重点探讨JVM的非堆内存,并讨论其默认值。
1. 概述非堆内存指的是JVM中用于存放类信息、常量池、静态变量等数据的内存空间。
与堆内存不同的是,非堆内存的内存空间是JVM自行管理的,不会进行垃圾回收。
2. 非堆内存的分类在JVM中,非堆内存主要分为两类:永久代(Permanent Generation)和元空间(Metaspace)。
2.1 永久代(已过时)永久代是Java 7及更早版本中用于存储类信息、常量池等内容的内存区域。
它的大小由`-XX:PermSize`和`-XX:MaxPermSize`参数控制,默认的初始大小为20MB,最大大小为64MB。
然而,永久代在JVM中存在多种问题,例如内存泄漏和内存溢出等。
因此,自Java 8开始,永久代被元空间所取代。
2.2 元空间元空间是Java 8及更高版本中引入的非堆内存区域,用于存储类信息、常量池等内容。
与永久代不同的是,元空间的大小不再受限于固定的堆内存大小,而是可以根据应用程序的需要进行动态调整。
元空间的大小由`-XX:MetaSpaceSize`和`-XX:MaxMetaspaceSize`参数控制,默认的初始大小为21MB,最大大小为无限制(Unlimited)。
3. 非堆内存默认值在大多数情况下,JVM的非堆内存默认值已经足够满足常规的Java应用程序需求。
然而,在某些特殊情况下,可能需要调整非堆内存的默认值以提升性能或解决特定的问题。
3.1 Java虚拟机默认值在没有显式指定非堆内存相关参数的情况下,JVM的默认非堆内存大小的设置如下:- 在Java 7及更早版本中,默认的非堆内存大小为20MB,即永久代的初始大小。
大数据开发工程师的岗位要求共五个岗位要求1:1、本科以上学历,5年及以上大数据设计与开发经验;2、理解大数据平台工具原理并能熟练使用,限于Hadoop/Spark、Hbase、Hive、Kafka、Flink等。
3、理解内存数据库原理并能熟练使用;4、熟练使用Java、Python等开发语言能力5、有任务调度系统的实战经验,能够基于业务需求拆分、组合串联子任务,端到端完成数据处理6、沟通能力强,良好的团队协作,以解决业务问题为导向,认同技术解决业务问题的价值理念,对处理海量大数据有较强的兴趣度和持续的热情岗位要求2:1、本科及以上学历,计算机科学与技术相关专业,具备扎实的计算机基础和数据结构与调优功底;2、对Hadoop/Spark/Flink/Presto/doris等开源组件,有大规模分布式系统的研发和优化经验;3、熟悉SQL引擎内核优化;4、熟悉数据存储、以及索引技术;5、精通scala/Java编程语言。
岗位要求3:1、大学本科及以上学历,计算机科学与技术类、信息与通信工程类、数学类、电子科学与技术类、控制科学与工程类、电子与信息类等相关专业优先;2、具有良好的程序设计和实现能力,熟悉Java语言,深入理解JVM;3、熟悉数据库和Linux系统相关知识,了解大数据相关技术;4、熟悉hadoop ecosystem常用开源框架者优先,如Hadoop/flink/spark等;5、做事严谨踏实,责任心强,条理清楚,善于学习总结,有良好的团队合作精神和沟通协调能力。
岗位要求4:1.三年以上开发经验,有报表工作经验,最好大数据统计,思维灵活能处理多表关联问题,了解一定的sql调优;2.熟悉大数据生态组件Hadoop、Hbase、Hive、Spark、Hue、Sqoop等,有源代码优化经验的优先;3.有大数据平台(CDH、Apache Hadoop等)的搭建和维护经验;4.数据Java编程,熟悉Java Api,熟悉多线程编程;5.熟悉数据库(Oracle、Mysql),熟悉SQL优化;6.项目经验丰富,并有过较大、较完整项目的开发经验。
jvm常用调优参数
JVM是JavaVirtualMachine的缩写,是Java程序运行的核心。
JVM的调优是优化Java应用程序性能的重要一环,其中调优参数的合理设置是关键。
以下是常用的JVM调优参数:
1. -Xms:设置JVM的初始内存大小,默认为物理内存的
1/64。
2. -Xmx:设置JVM的最大内存大小,超出该内存大小后会触发垃圾回收。
3. -Xmn:设置年轻代的大小,一般设置为总内存的1/3或
1/4。
4. -XX:SurvivorRatio:设置年轻代中Eden区和Survivor区的比例,默认值为8。
5. -XX:NewRatio:设置新生代和老年代的比例,默认值为2。
6. -XX:MaxPermSize:设置永久代的大小,一般设置为
256MB。
7. -XX:+UseConcMarkSweepGC:使用CMS垃圾回收器,可以减少内存抖动。
8. -XX:+UseParallelGC:使用并行垃圾回收器,可提高垃圾回收效率。
9. -XX:+HeapDumpOnOutOfMemoryError:当JVM内存溢出时,生成堆转储文件。
10. -XX:+PrintGCDetails:打印垃圾回收的详细信息。
以上是常用的JVM调优参数,通过合理地设置参数,可以优化Java应用程序的性能。
java8 jvm参数Java 8 JVM参数在Java开发中,JVM(Java Virtual Machine)参数是非常重要的一部分,它可以对Java程序的性能和行为进行调优和配置。
本文将介绍一些常用的Java 8 JVM参数,并讨论它们的作用和用法。
一、堆内存参数1. -Xms:指定JVM的初始堆内存大小。
比如,-Xms512m表示初始堆内存为512MB。
2. -Xmx:指定JVM的最大堆内存大小。
比如,-Xmx1024m表示最大堆内存为1GB。
3. -Xmn:指定JVM的新生代内存大小。
新生代内存主要用于存放新创建的对象。
比如,-Xmn256m表示新生代内存为256MB。
4. -XX:NewRatio:指定新生代和老年代内存的比例。
默认值为2,表示新生代和老年代的比例为1:2。
5. -XX:SurvivorRatio:指定Eden区和Survivor区的比例。
默认值为8,表示Eden区和Survivor区的比例为8:1。
二、垃圾回收参数1. -XX:+UseSerialGC:使用串行垃圾回收器。
适用于单线程环境,对于小型应用或测试环境比较适用。
2. -XX:+UseParallelGC:使用并行垃圾回收器。
适用于多核处理器环境,可以充分利用多核的性能。
3. -XX:+UseConcMarkSweepGC:使用CMS(Concurrent Mark Sweep)垃圾回收器。
适用于对响应时间有较高要求的场景,能够减少垃圾回收暂停时间。
4. -XX:+UseG1GC:使用G1(Garbage First)垃圾回收器。
适用于大内存应用和服务器环境,能够更好地管理堆内存。
5. -XX:MaxGCPauseMillis:设置垃圾回收暂停时间的目标值。
默认值为200ms。
三、调优参数1. -XX:MetaspaceSize:指定元空间(Metaspace)的初始大小。
元空间主要用于存放类的元数据信息。
jvm监控指标JVM(Java虚拟机)监控指标是用于监控JVM的性能、健康状况和资源利用率的指标。
这些指标对于JVM的管理和调优非常重要。
以下是一些常见的JVM监控指标,可以帮助开发人员和系统管理员更好地了解JVM的运行情况。
1.内存使用-堆内存使用情况:包括堆内存的大小、已使用的堆内存量以及垃圾回收的情况。
-非堆内存使用情况:包括非堆内存的大小、已使用的非堆内存量。
-GC统计信息:包括GC的次数、时间、暂停时间等。
2.类加载-已加载的类数量:显示当前已加载的类的数量。
-类加载的时间:显示类加载的时间,可以帮助识别潜在的性能问题。
3.线程-活跃线程数量:显示当前活跃的线程数目。
-线程CPU时间:显示线程的CPU使用时间,可以帮助识别线程是否过于繁忙。
4.垃圾回收(GC)-GC时间:显示GC的时间,包括GC的总时间、平均每次GC的时间等。
-对象的分配速率:显示JVM每秒钟分配对象的速率。
5.文件描述符-打开的文件描述符数量:显示已打开的文件描述符的数量,可以帮助检测是否存在文件句柄泄漏。
6.CPU使用率-JVM的CPU使用率:显示JVM的CPU使用率,可以帮助识别JVM是否过于繁忙。
7.网络IO-网络IO的吞吐量:显示网络数据的传输速率。
-网络连接数量:显示已建立的网络连接数量。
8.磁盘IO-磁盘IO的吞吐量:显示磁盘数据读写的速率。
-磁盘空间使用情况:显示磁盘使用量、剩余空间等。
9.JVM运行状态-JVM运行时间:显示JVM已运行的时间。
-JVM进程ID:显示JVM的进程ID。
10.错误和异常-异常数量:显示抛出的异常数量。
-错误数量:显示发生的错误数量。
这些监控指标可以通过不同的工具和技术来收集和分析,比如使用JMX,可以通过JConsole、Java Mission Control等工具来监控JVM。
此外,还有很多第三方监控工具,比如VisualVM、Grafana等,可以提供更丰富的监控指标和可视化图表,帮助开发人员和系统管理员更好地了解JVM的运行情况,以便进行调优和故障排查。
一、介绍Java虚拟机(JVM)是一种能够在计算机上运行Java程序的虚拟机。
在Java应用程序运行的过程中,JVM会使用堆内存来存储对象实例。
堆内存的大小会直接影响程序的性能和稳定性。
了解JVM堆内存的扩容机制以及缩容机制对于Java开发人员来说是非常重要的。
二、堆内存的扩容机制1. 初始内存和最大内存在启动Java程序时,可以通过设置参数-Xms和-Xmx来指定JVM堆内存的初始大小和最大大小。
初始内存指定JVM堆内存的初始大小,最大内存指定JVM堆内存的最大大小。
当JVM启动时,会先分配初始内存,并且在应用程序运行中达到初始内存的上限时,堆内存会自动扩容。
当堆内存扩容达到最大内存时,程序会抛出内存溢出错误。
2. 自动扩容JVM堆内存的自动扩容是由垃圾回收器(GC)来完成的。
当堆内存中的对象实例占用的空间超过了当前内存的剩余空间时,GC会触发一次垃圾回收操作,释放部分无用对象实例的内存空间,从而使堆内存得以扩容。
这种自动扩容机制可以有效地避免了由于堆内存空间不足而导致的程序性能下降或者程序崩溃的情况。
三、堆内存的缩容机制1. 内存回收JVM堆内存的缩容机制是由GC和虚拟机内部的内存管理器来完成的。
当堆内存中的对象实例占用的空间下降到一定程度时,内存管理器会自动触发一次内存回收操作,将不再使用的内存空间释放出来,从而使堆内存得以缩容。
这种自动缩容机制可以帮助程序及时释放不再使用的内存空间,提高堆内存的利用率,从而提升程序的性能和稳定性。
2. 手动内存回收除了自动内存回收之外,开发人员也可以通过调用System.gc()方法手动触发一次垃圾回收操作,来释放不再使用的内存空间。
这种手动的内存回收操作也可以帮助程序及时释放内存空间,提高程序的性能和稳定性。
四、总结JVM堆内存的扩容机制和缩容机制是保障Java程序高性能和稳定运行的重要环节。
通过合理设置初始内存和最大内存参数,以及合理使用垃圾回收器和内存管理器,可以有效地管理JVM堆内存的扩容和缩容,从而提高程序的性能和稳定性。
Java架构师的岗位职责Java架构师的岗位职责1职责:1、负责系统架构设计工作,并对相关应用架构规划进行建议、评价及落实执行。
2、负责核心开发技术的攻关,组织解决项目开发过程中的技术难题。
3、负责软件产品和项目的技术路线研究和制定。
4、负责系统优化,能准确捕捉系统性能瓶颈,并提出解决方案。
5、参与数据库设计工作。
6、参与制定软件设计开发规范。
7、参与设计开发的评审、互查和讨论会。
任职资格1、计算机科学或相关专业,统招本科以上学历。
2、具备软件系统架构的分析和设计能力以及软件开发的`计划和监控能力。
3、精通Java语言,具有Windows、Linux、Unix系统环境下的应用软件开发经验。
熟悉主流技术框架的原理与方法。
4、至少五年应用软件公司软件系统架构和设计的工作经验。
5、思维敏捷、具有创新精神和意识,具有独立专研精神,善于学习,善于沟通,富有团队精神,能够承担压力。
Java架构师的岗位职责2职责:1、负责Java/BS系统总体设计:应用架构设计、开发框架搭建、开发规范制定,指导团队进行业务模块代码编写;2、优化现有架构,设计的新架构,解决现有技术架构的瓶颈;协助解决平台中升级事件的技术问题;3、负责建立高效的设计、开发和测试的辅助软件工具环境;3、进行系统技术平台的选型和评估新技术的.可行性;4、参与需求评审,主导技术方案编写,有一定的项目及团队协作能力。
任职要求:1. 本科及以上学历,计算机,软件工程及相关专业,本科5年以上JAVA开发经验;2. 熟练掌握java技术,对多线程、数据结构有清晰的认识;3. 熟悉JVM原理,熟悉高并发的网络架构和分布式系统;4. 熟悉Oracle等数据库,有实际应用开发经验;5. 具有较强的编程能力,能够完成较复杂的交互流程设计和实现,具备良好的编程习惯,能够编写高质量技术文档;6. 熟悉开源框架如Struts2、WebService、mybatis、springMVC,spring boot 等;7. 需要较强的逻辑分析、数据分析、问题排查能力,沟通能力,工作主动,学习能力强。
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栈、程序计数器和本地方法栈这五个部分,这几个部分和类装载机制与运行引擎机制一起组成的体系结构图为:图3 JVM的体系结构JVM的每个实例都有一个它自己的方法域和一个堆,运行于JVM内的所有的线程都共享这些区域;当虚拟机装载类文件的时候,它解析其中的二进制数据所包含的类信息,并把它们放到方法域中;当程序运行的时候,JVM把程序初始化的所有对象置于堆上;而每个线程创建的时候,都会拥有自己的程序计数器和 Java 栈,其中程序计数器中的值指向下一条即将被执行的指令,线程的Java栈则存储为该线程调用Java方法的状态;本地方法调用的状态被存储在本地方法栈,该方法栈依赖于具体的实现。
下面分别对这几个部分进行说明。
执行引擎处于JVM的核心位置,在Java虚拟机规范中,它的行为是由指令集所决定的。
尽管对于每条指令,规范很详细地说明了当JVM执行字节码遇到指令时,它的实现应该做什么,但对于怎么做却言之甚少。
Java虚拟机支持大约248个字节码。
每个字节码执行一种基本的CPU运算,例如,把一个整数加到寄存器,子程序转移等。
Java指令集相当于Java程序的汇编语言。
Java指令集中的指令包含一个单字节的操作符,用于指定要执行的操作,还有0个或多个操作数,提供操作所需的参数或数据。
许多指令没有操作数,仅由一个单字节的操作符构成。
虚拟机的内层循环的执行过程如下:do{取一个操作符字节;根据操作符的值执行一个动作;}while(程序未结束)由于指令系统的简单性,使得虚拟机执行的过程十分简单,从而有利于提高执行的效率。
指令中操作数的数量和大小是由操作符决定的。
如果操作数比一个字节大,那么它存储的顺序是高位字节优先。
例如,一个16位的参数存放时占用两个字节,其值为:第一个字节*256+第二个字节字节码。
指令流一般只是字节对齐的。
指令tableswitch和lookup是例外,在这两条指令内部要求强制的4字节边界对齐。
对于本地方法接口,实现JVM并不要求一定要有它的支持,甚至可以完全没有。
Sun公司实现Java本地接口(JNI)是出于可移植性的考虑,当然我们也可以设计出其它的本地接口来代替Sun公司的JNI。
但是这些设计与实现是比较复杂的事情,需要确保垃圾回收器不会将那些正在被本地方法调用的对象释放掉。
Java的堆是一个运行时数据区,类的实例(对象)从中分配空间,它的管理是由垃圾回收来负责的:不给程序员显式释放对象的能力。
Java不规定具体使用的垃圾回收算法,可以根据系统的需求使用各种各样的算法。
Java方法区与传统语言中的编译后代码或是Unix进程中的正文段类似。
它保存方法代码(编译后的java代码)和符号表。
在当前的Java实现中,方法代码不包括在垃圾回收堆中,但计划在将来的版本中实现。
每个类文件包含了一个Java类或一个Java界面的编译后的代码。
可以说类文件是 Java语言的执行代码文件。
为了保证类文件的平台无关性,Java虚拟机规范中对类文件的格式也作了详细的说明。
其具体细节请参考Sun公司的Java 虚拟机规范。
Java虚拟机的寄存器用于保存机器的运行状态,与微处理器中的某些专用寄存器类似。
Java虚拟机的寄存器有四种:1.pc: Java程序计数器;2.optop: 指向操作数栈顶端的指针;3.frame: 指向当前执行方法的执行环境的指针;。
4.vars: 指向当前执行方法的局部变量区第一个变量的指针。
在上述体系结构图中,我们所说的是第一种,即程序计数器,每个线程一旦被创建就拥有了自己的程序计数器。
当线程执行Java方法的时候,它包含该线程正在被执行的指令的地址。
但是若线程执行的是一个本地的方法,那么程序计数器的值就不会被定义。
Java虚拟机的栈有三个区域:局部变量区、运行环境区、操作数区。
局部变量区每个Java方法使用一个固定大小的局部变量集。
它们按照与vars寄存器的字偏移量来寻址。
局部变量都是32位的。
长整数和双精度浮点数占据了两个局部变量的空间,却按照第一个局部变量的索引来寻址。
(例如,一个具有索引n的局部变量,如果是一个双精度浮点数,那么它实际占据了索引n和n+1所代表的存储空间)虚拟机规范并不要求在局部变量中的64位的值是64位对齐的。
虚拟机提供了把局部变量中的值装载到操作数栈的指令,也提供了把操作数栈中的值写入局部变量的指令。
运行环境区在运行环境中包含的信息用于动态链接,正常的方法返回以及异常捕捉。
动态链接运行环境包括对指向当前类和当前方法的解释器符号表的指针,用于支持方法代码的动态链接。
方法的class文件代码在引用要调用的方法和要访问的变量时使用符号。
动态链接把符号形式的方法调用翻译成实际方法调用,装载必要的类以解释还没有定义的符号,并把变量访问翻译成与这些变量运行时的存储结构相应的偏移地址。
动态链接方法和变量使得方法中使用的其它类的变化不会影响到本程序的代码。
正常的方法返回如果当前方法正常地结束了,在执行了一条具有正确类型的返回指令时,调用的方法会得到一个返回值。
执行环境在正常返回的情况下用于恢复调用者的寄存器,并把调用者的程序计数器增加一个恰当的数值,以跳过已执行过的方法调用指令,然后在调用者的执行环境中继续执行下去。
异常捕捉异常情况在Java中被称作Error(错误)或Exception(异常),是Throwable类的子类,在程序中的原因是:①动态链接错,如无法找到所需的class文件。
②运行时错,如对一个空指针的引用。
程序使用了throw语句。
当异常发生时,Java虚拟机采取如下措施:∙检查与当前方法相联系的catch子句表。
每个catch子句包含其有效指令范围,能够处理的异常类型,以及处理异常的代码块地址。
∙与异常相匹配的catch子句应该符合下面的条件:造成异常的指令在其指令范围之内,发生的异常类型是其能处理的异常类型的子类型。
如果找到了匹配的catch子句,那么系统转移到指定的异常处理块处执行;如果没有找到异常处理块,重复寻找匹配的catch子句的过程,直到当前方法的所有嵌套的 catch子句都被检查过。
∙由于虚拟机从第一个匹配的catch子句处继续执行,所以catch子句表中的顺序是很重要的。
因为Java代码是结构化的,因此总可以把某个方法的所有的异常处理器都按序排列到一个表中,对任意可能的程序计数器的值,都可以用线性的顺序找到合适的异常处理块,以处理在该程序计数器值下发生的异常情况。
∙如果找不到匹配的catch子句,那么当前方法得到一个"未截获异常"的结果并返回到当前方法的调用者,好像异常刚刚在其调用者中发生一样。
如果在调用者中仍然没有找到相应的异常处理块,那么这种错误将被传播下去。
如果错误被传播到最顶层,那么系统将调用一个缺省的异常处理块。
操作数栈区机器指令只从操作数栈中取操作数,对它们进行操作,并把结果返回到栈中。
选择栈结构的原因是:在只有少量寄存器或非通用寄存器的机器(如 Intel486)上,也能够高效地模拟虚拟机的行为。
操作数栈是32位的。
它用于给方法传递参数,并从方法接收结果,也用于支持操作的参数,并保存操作的结果。
例如,iadd指令将两个整数相加。
相加的两个整数应该是操作数栈顶的两个字。