㈠ 如何设置myeclipse的jvm启动参数
-Xint
设置jvm以解释模式运行,所有的字节码将被直接执行,而不会编译成本地码。
-Xbatch
关闭后台代码编译,强制在前台编译,编译完成之后才能进行代码执行;
默认情况下,jvm在后台进行编译,若没有编译完成,则前台运行代码时以解释模式运行。
-Xbootclasspath:bootclasspath
让jvm从指定路径(可以是分号分隔的目录、jar、或者zip)中加载bootclass,用来替换jdk的rt.jar;若非必要,一般不会用到;
-Xbootclasspath/a:path
将指定路径的所有文件追加到默认bootstrap路径中;
-Xbootclasspath/p:path
让jvm优先于bootstrap默认路径加载指定路径的所有文件;
-Xcheck:jni
对JNI函数进行附加check;此时jvm将校验传递给JNI函数参数的合法性,在本地代码中遇到非法数据时,jmv将报一个致命错误而终止;使用该参数后将造成性能下降,请慎用。
-Xfuture
让jvm对类文件执行严格的格式检查(默认jvm不进行严格格式检查),以符合类文件格式规范,推荐开发人员使用该参数。
-Xnoclassgc
关闭针对class的gc功能;因为其阻止内存回收,所以可能会导致OutOfMemoryError错误,慎用;
-Xincgc
开启增量gc(默认为关闭);这有助于减少长时间GC时应用程序出现的停顿;但由于可能和应用程序并发执行,所以会降低CPU对应用的处理能力。
-Xloggc:file
与-verbose:gc功能类似,只是将每次GC事件的相关情况记录到一个文件中,文件的位置最好在本地,以避免网络的潜在问题。
若与verbose命令同时出现在命令行中,则以-Xloggc为准。
-Xmsn
指定jvm堆的初始大小,默认为物理内存的1/64,最小为1M;可以指定单位,比如k、m,若不指定,则默认为字节。
-Xmxn
指定jvm堆的最大值,默认为物理内存的1/4或者1G,最小为2M;单位与-Xms一致。
-Xprof
跟踪正运行的程序,并将跟踪数据在标准输出输出;适合于开发环境调试。
-Xrs
减少jvm对操作系统信号(signals)的使用,该参数从1.3.1开始有效;
从jdk1.3.0开始,jvm允许程序在关闭之前还可以执行一些代码(比如关闭数据库的连接池),即使jvm被突然终止;
jvm 关闭工具通过监控控制台的相关事件而满足以上的功能;更确切的说,通知在关闭工具执行之前,先注册控制台的控制handler,然后对 CTRL_C_EVENT, CTRL_CLOSE_EVENT, CTRL_LOGOFF_EVENT, and
CTRL_SHUTDOWN_EVENT这几类事件直接返回true。
但如果jvm以服务的形式在后台运行(比如servlet引擎),他能接 收CTRL_LOGOFF_EVENT事件,但此时并不需要初始化关闭程序;为了避免类似冲突的再次出现,从jdk1.3.1开始提供-Xrs参数;当此 参数被设置之后,jvm将不接收控制台的控制handler,也就是说他不监控和处理CTRL_C_EVENT, CTRL_CLOSE_EVENT, CTRL_LOGOFF_EVENT, or
CTRL_SHUTDOWN_EVENT事件。
-Xssn
设置单个线程栈的大小,一般默认为512k。
上面这些参数中,比如-Xmsn、-Xmxn……都是我们性能优化中很重要的参数;
-Xprof、-Xloggc:file等都是在没有专业跟踪工具情况下排错的好手;
在上一小节中提到的关于JProfiler的配置中就使用到了-Xbootclasspath/a:path;
非Stable参数
前面我们提到用-XX作为前缀的参数列表在jvm中可能是不健壮的,SUN也不推荐使用,后续可能会在没有通知的情况下就直接取消了;但是由于这些参数中的确有很多是对我们很有用的,比如我们经常会见到的-XX:PermSize、-XX:MaxPermSize等等;
下面我们将就java HotSpot VM中-XX:的可配置参数列表进行描述;
这些参数可以被松散的聚合成三类:
行为参数(Behavioral Options):用于改变jvm的一些基础行为;
性能调优(Performance Tuning):用于jvm的性能调优;
调试参数(Debugging
Options):一般用于打开跟踪、打印、输出等jvm参数,用于显示jvm更加详细的信息;
由于sun官方文档中对各参数的描述也都非常少(大多只有一句话),而且大多涉及OS层面的东西,很难描述清楚,所以以下是挑选了一些我们开发中可能会用得比较多的配置项,若需要查看所有参数列表,可以点击HotSpot VM Specific
Options.查看原文;
首先来介绍行为参数:
参数及其默认值
描述
-XX:-DisableExplicitGC
禁止调用System.gc();但jvm的gc仍然有效
-XX:+MaxFDLimit
最大化文件描述符的数量限制
-XX:+ScavengeBeforeFullGC
新生代GC优先于Full GC执行
-XX:+UseGCOverheadLimit
在抛出OOM之前限制jvm耗费在GC上的时间比例
-XX:-UseConcMarkSweepGC
对老生代采用并发标记交换算法进行GC
-XX:-UseParallelGC
启用并行GC
-XX:-UseParallelOldGC
对Full GC启用并行,当-XX:-UseParallelGC启用时该项自动启用
-XX:-UseSerialGC
启用串行GC
-XX:+UseThreadPriorities
启用本地线程优先级
上面表格中黑体的三个参数代表着jvm中GC执行的三种方式,即串行、并行、并发;
串行(SerialGC)是jvm的默认GC方式,一般适用于小型应用和单处理器,算法比较简单,GC效率也较高,但可能会给应用带来停顿;
并行(ParallelGC)是指GC运行时,对应用程序运行没有影响,GC和app两者的线程在并发执行,这样可以最大限度不影响app的运行;
并发(ConcMarkSweepGC)是指多个线程并发执行GC,一般适用于多处理器系统中,可以提高GC的效率,但算法复杂,系统消耗较大;
性能调优参数列表:
参数及其默认值
描述
-XX:LargePageSizeInBytes=4m
设置用于Java堆的大页面尺寸
-XX:MaxHeapFreeRatio=70
GC后java堆中空闲量占的最大比例
-XX:MaxNewSize=size
新生成对象能占用内存的最大值
-XX:MaxPermSize=64m
老生代对象能占用内存的最大值
-XX:MinHeapFreeRatio=40
GC后java堆中空闲量占的最小比例
-XX:NewRatio=2
新生代内存容量与老生代内存容量的比例
-XX:NewSize=2.125m
新生代对象生成时占用内存的默认值
-XX:ReservedCodeCacheSize=32m
保留代码占用的内存容量
-XX:ThreadStackSize=512
设置线程栈大小,若为0则使用系统默认值
-XX:+UseLargePages
使用大页面内存
我们在日常性能调优中基本上都会用到以上黑体的这几个属性;
调试参数列表:
参数及其默认值
描述
-XX:-CITime
打印消耗在JIT编译的时间
-XX:ErrorFile=./hs_err_pid.log
保存错误日志或者数据到文件中
-XX:-ExtendedDTraceProbes
开启solaris特有的dtrace探针
-XX:HeapDumpPath=./java_pid.hprof
指定导出堆信息时的路径或文件名
-XX:-HeapDumpOnOutOfMemoryError
当首次遭遇OOM时导出此时堆中相关信息
-XX:
出现致命ERROR之后运行自定义命令
-XX:OnOutOfMemoryError=";"
当首次遭遇OOM时执行自定义命令
-XX:-PrintClassHistogram
遇到Ctrl-Break后打印类实例的柱状信息,与jmap -histo功能相同
-XX:-PrintConcurrentLocks
遇到Ctrl-Break后打印并发锁的相关信息,与jstack -l功能相同
-XX:-PrintCommandLineFlags
打印在命令行中出现过的标记
-XX:-PrintCompilation
当一个方法被编译时打印相关信息
-XX:-PrintGC
每次GC时打印相关信息
-XX:-PrintGC Details
每次GC时打印详细信息
-XX:-PrintGCTimeStamps
打印每次GC的时间戳
-XX:-TraceClassLoading
跟踪类的加载信息
-XX:-TraceClassLoadingPreorder
跟踪被引用到的所有类的加载信息
-XX:-TraceClassResolution
跟踪常量池
-XX:-TraceClassUnloading
跟踪类的卸载信息
-XX:-TraceLoaderConstraints
跟踪类加载器约束的相关信息
㈡ java中将java源文件编译成字节码文件这个过程是由JVM执行的吗
不是,JVM只是执行编译以后的字节码,编译是由javac(java编译器)执行的。
㈢ jdk中两个重要可执行程序分别是什么
JDK是SUN公司提供的一套Java开发环境,
其中包含Java编译器、Java运行工具、Java文档生成工具、以及Java打包工具。
在JDK的bin目录下存放了很多可执行文件,其中最重要的就是java.exe和javac.exe、举例说明:
_正常我们编写好程序存放在源文件a.java中,之后会通过javac.exe(Java编译器工具)进行编译,编译完成后会生成a.class文件(字节码文件,是可执行的java程序),
_然后接下来java.exe(Java运行工具)会启动JVM(Java虚拟机)进程,Java虚拟机相当于一个小型的操作系统,它专门负责运行由Java编译器生成的字节码文件(a.class),从而使程序运行。
㈣ 简述jvm工作原理
Java是一种技术,它由四方面组成:Java编程语言、Java类文件格式、Java虚拟机和Java应用程序接口(Java API)。
运行期环境代表着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 的平台无关性。
JVM在它的生存周期中有一个明确的任务,那就是运行Java程序,因此当Java程序启动的时候,就产生JVM的一个实例;当程序运行结束的时候,该实例也跟着消失了。下面我们从JVM的体系结构和它的运行过程这两个方面来对它进行比较深入的研究。
1、Java虚拟机的体系结构
·每个JVM都有两种机制:
①类装载子系统:装载具有适合名称的类或接口
②执行引擎:负责执行包含在已装载的类或接口中的指令
·每个JVM都包含:
方法区、Java堆、Java栈、本地方法栈、指令计数器及其他隐含寄存器
2、Java代码编译和执行的整个过程
也正如前面所说,Java代码的编译和执行的整个过程大概是:开发人员编写Java代码(.java文件),然后将之编译成字节码(.class文件),再然后字节码被装入内存,一旦字节码进入虚拟机,它就会被解释器解释执行,或者是被即时代码发生器有选择的转换成机器码执行。
(1)Java代码编译是由Java源码编译器来完成,也就是Java代码到JVM字节码(.class文件)的过程。
2)Java字节码的执行是由JVM执行引擎来完成
Java代码编译和执行的整个过程包含了以下三个重要的机制:
·Java源码编译机制
·类加载机制
·类执行机制
(1)Java源码编译机制
Java 源码编译由以下三个过程组成:
①分析和输入到符号表
②注解处理
③语义分析和生成class文件
最后生成的class文件由以下部分组成:
①结构信息:包括class文件格式版本号及各部分的数量与大小的信息
②元数据:对应于Java源码中声明与常量的信息。包含类/继承的超类/实现的接口的声明信息、域与方法声明信息和常量池
③方法信息:对应Java源码中语句和表达式对应的信息。包含字节码、异常处理器表、求值栈与局部变量区大小、求值栈的类型记录、调试符号信息
(2)类加载机制 JVM的类加载是通过ClassLoader及其子类来完成的
㈤ Java编译成字节码的阶段有用到JVM吗
应该是不需要jvm的,其实javac :即java compile ,是指java编译,java 运行文件,其实java命令就是调用的 jvm平台,交流一下吧,这是我一直以来的看法。
㈥ 运行一个项目的时候,jvm是一下把项目代码加载进jvm,还是运行到什么功能,在加载相应的代码
class文件是按需加载,发生以下情况,而当前运行环境中尚未加载对应的类时,JVM才会从文件系统中加载class文件到内存中:
一、遇到new、getstatic、putstatic、invokestatic这四条指令码时。
1、new关键字实例化一个类的时候。
2、读取或设置一个的类的静态字段的时候。限只在本类里定义的,继承父类的静态字段不算。静态常量不算。
3、调用一个类的静态方法时。
二、java.lang.reflect包的方法对类反射调用的时候。
三、初始化子类,父类没有初始化的时候初始化父类。
四、虚拟机启动时指定的主类会先被初始化。
㈦ 当使用 Java 命令运行 .class 文件的时候,就相当于启动了一个 JVM 进程,如何理解
进程是操作系统资源管理的基本单位,运行.class文件和打开一个应用软件(当然有些软件可能对于多个进程)是类似的,都会创建一个操作系统进程。
你提到的"运行.class启动的JVM进程",实际上这个就是操作系统创建的进程;这个进程需要一定的资源(CPU、内存、磁盘等)来完成一定的事情,进程之间不会相互干扰,所以每个软件都需要操作系统分配进程。
至于你说的"JVM中有哪些进程",我理解应该是"JVM中有哪些"线程;建议去了解一下进程和线程之间的区别。我个人理解进程和线程的核心区别是:进程是资源管理、分配的基本单位,这个类比于公司;而线程是操作系统调度的基本单位,类比于公司员工。上级部门在分配资源的时候肯定是分配名额到企业,但是分配资源具体怎么使用,则需要由企业的员工来完成。
一般JVM中的线程由用户创建,但是JVM也会默认创建一些线程,比如垃圾回收线程。
㈧ Java创建对象是在编译时还是在运行时
运行期。编译好的java程序(即.class文件)需要运行在JVM中。程序,无论代码还是数据,都需要存储在内存中。JVM为java程序提供并管理所需要的内存空间。JVM内存分为"堆"、"栈"、"方法区"三个区域,分别用于存储不同数据。首先JVM会检查创建这个对象的类是否是一个以前从没有见过的类型,如果不是,JVM将为其分配内存,如果是,java虚拟机将调用具体的ClassLoader找到对应的.class文件,并将这个文件的内容读到内存中去。
1)堆:
1.1)用于存储所有new出来的对象(包括成员变量)。
1.2)垃圾:没有任何引用所指向的对象。
垃圾回收器(GC)不定时到内存中清扫垃圾,
并不一定一发现垃圾就立刻回收,
回收过程是透明的(看不到的),
通过调用System.gc()可以建议虚拟机尽快调度GC来回收。
1.3)内存泄漏:不再使用的内存没有被及时的回收。
建议:不再使用的对象,及时将引用设置为null。
1.4)成员变量的生命周期:
创建对象时存储在堆中,对象被回收时一并被回收。
2)栈:
2.1)用于存储正在调用的方法中的所有局部变量(包括参数)
2.2)JVM会为每一个正在调用的方法分配一块对应的栈帧,
栈帧中存储方法中的局部变量(包括参数),
方法调用结束时,栈帧被清除,局部变量一并被清除。
2.3)局部变量的生命周期:
调用方法时存在栈中,方法结束时与栈帧一并被清除。
3)方法区:
3.1)用于存储.class字节码文件(包括方法)。
3.2)方法只有一份,通过this来区分具体的对象。
既然对象在堆中创建,因此Java创建对象是在运行时,而不是编译时。
㈨ 说说java文件编译时都做了哪些事情
java有反射机制,执行编译时会尝试找到JRE安装所在目录,然后找到jvm.dll,接着启动JVM进行初始化动作,产生3个类加载器,用来将所用到的类文件加载到内存中,会自动导入java.lang下的类文件和你想导入的类文件,查看你的代码中是否有未处理的可控式异常,JVM会查看你写的代码是否符合语法,.JVM会将你所写的java文件编译为与系统平台无关的字节码文件。
㈩ Java编译运行过程
程序员所编写的是以.java为后缀的文件,此文件操作系统不能正确识别,因此,首先要经过编译,生成所谓的字节码文件(.class),而字节码文件需要JVM来提供运行环境的支持。
JVM是一个软件,安装在操作系统中,是建立在操作系统之上的,为字节码文件提供运行环境,效果如图 – 1 所示。
图- 1
Java官方提供了针对不同平台的JVM软件,即:不同平台的JVM是不同的。但这些JVM遵循着相同的标准,即:只要是标准的.class文件,就可以在不同的JVM上运行,而且运行的效果相同。这样,就实现了所谓的“一次编程到处使用”。效果如图– 2所示:
图- 2
Java程序遵循着先编译、后执行的原则。首先,通过javac命令将JAVA源程序(.java文件)编译为JAVA字节码(.class文件),而后,通过java命令启动JVM,由JVM来加载.class文件并运行.class文件。效果如图 – 3所示:
图- 3