其实在JAVA中,虚拟机参数主要起到的作用,在虚拟机运行的时候,在程序运行的时候,这个虚拟机的调配,
参数会对应用系统的运行的良好,性能等等都会产生直接的关系,比如说我们有两个方面
堆参数的分配
大多数的参数都是为堆去服务的,为内存memorgy去服务的,这是很关键的一个点,首先我们看看有这个几个参数
在JAVA虚拟机里面都叫-XX来打印一下配置信息,-XX打头的基本上来讲都是配置虚拟机的一些应用程序上的,
或者打印一些log日志级别的东西
我们来看一看有一个pringGC,如果你使用了这个参数了
-XX:PrintGC 如果你使用了这个参数了,在你虚拟机启动之后,只要遇到GC就会打印日志,
-XX:+UseSerialGC 这个-XX就表示对于系统级别的,JVM层次的一些配置,比如说配置一些日志信息,刚刚都看到
了,只要经历一次GC,它经历垃圾回收之后就会打印日志,你配置什么样的垃圾回收器,JVM使用什么样的垃圾回收器
都是可以去配置的,就是建立在系统级别的,非-XX 基本上都是对 应用层面上的配置,都是对运行在虚拟机之上的,
应用系统,APP应用程序,给他设置一些内存的大小,方法区栈的大小,是这种级别的配置,这是两块不同的点.
你在学之前都要了解,这里的配置有一个加号+,加号表示启用的意思,减号-表示禁用,对于参数的一些配置无非
-XX:+PrintGC 是配置在虚拟机级别的,只要经历过GC的话,我虚拟机遇到GC就会打印日志.
-XX:+UseSerialGC 配置垃圾回收器,SerialGC这是一种非常古老的串行收集器,以后我们会学习一些其它的
垃圾回收机制,比如G1,比如CMS,还有并行的垃圾回收器,这些会随着垃圾回收机制的不同,它会大大的影响你的
JVM,你的性能,这个影响是很大的
-XX:+PrintGCDetail 打印详细信息,包括各个区的情况,各个区指的是什么区啊,新生代老年代,然后永久区,
然后再详细一点,新生代分eden区,s0区,s1区,老年代,永久区,就是detail会打印很详细的信息
非-XX,只是针对你的应用层的
-Xms 指的是初始化,应用层初始化的大小,其实你熟悉了就知道了,500M内存,
-XmX 表示这个应用程序能够获得的最大堆内存大小,最大上限Max
-XX:PrintCommandLineFlags 可以将隐式或者显示的传给虚拟机的参数输出
比如 java -jar -XX..... 配置了一堆东西,你加上-XX:PringCommandLineFlags这么一句话,它就会把
运行你配置的一些配置项,都能打印出来,就是你配置的一些内容能够打印,输出一下,这几点你了解明白了之后
我直接依赖eclipse做一些命令
Run As ----> Run Configration---->去配置一些参数
arguments,第一个参数是传到main方法里面了,我们一般很少去配置第一块 Program arguments
下面的这块指的是VM arguments,你跑这个程序JAVA虚拟机会给你怎么去调配
-XX:+PrintGC -Xms5m -Xmx20m -XX:+UseSerialGC -XX:+PrintGCDetails
串行的垃圾回收器,然后打印一些详细的信息
配置的时候一定要选中Test01
你写一行配置是最好的了
程序刚进入主函数的时候,我们先看看,首先max memory,free memory,total memory就是最大的,空闲的,
总共的内存
我们看执行的结果
上面有一行
-XX:InitialHeapSize 15M, -XX:MaxHeapSize 20M, -XX:PrintCommandLineFlags 你看到这些和我们
刚刚在arguments里面配置是一样吗,因为你加了-XX:PrintCommandLineFlags这个参数了,如果你把这个参数
去掉的话,控制台第一行就没有了,max memory 是20M, 就是最大的20M,然后呢是 free memory,这是空闲的,
但是并不是那么准确,主函数启动肯定也会占用一定的内存,操作系统级别的原因,影响你的free memory肯定不会
那么准确,total memory当前我们的系统,正在使用的内存,正常我们初始化的时候我们分配了5M内存,但是由于
各个系统不确定的原因,可能我在跑主函数的时候,消耗了一定的内存,我在JVM运行的时候,由于硬件的原因,
不是那么特别好,也是那么适当的去吃了一点点内存,这就不是那么准确的,所以我们发现我们的free memory,
真正空闲的memory, 有分配的给你5M,空闲的才4M多,也就是少了那么0.几兆,这个是和你自己本身的机器,你可能
机器的越好,吃内存的情况就越少,这个没法确定,但是有一点我们可以确定,你的total memory,5M没问题,
因为系统初始化的时候我们就分配了5M,第一次打印你就可以理解为系统初始化了,就是total memory,
以后可能有其他情况,以后 total memory 可能会有变化的,所以这是一个经验的积累,为什么不准确的呢,
你有没有发现linux操作系统也是一样,比如我分配了两个G的内存过去,然后我们 free -m,或者我们free看一下,
就是少了那么0.1,大家不知道你仔细看了没有,如果你玩linux敲这个命令,你用了VMare分配了1G的内存,一定
是1024这个数吗,我估计它是900多,或者800多,
这是1024bit*1的话是1k,1k*1024是1M,也就是我这个代码先分配了1M内存,相当于我运行这段程序的时候,
使用了1M的内存,只要分配一兆内存以后就会分配一次GC
658K回收到了127K,回收了将近0.5M,经历过一次GC之后,前面这个数字回收之前的,后面这个数字GC之后的,
然后呢再往下看
max memory是恒定的,20M不用管,原先我们的有4M空闲的内存,然后分配了1M,是不是剩3M多,JVM你看了结果之后
一般都是大约,相似度是百分之90左右,不可能是非常非常的精确,内存这个数是操作系统管的,那么我们会发现
一个很明显的下降,就是这个值差了1M,就是这段你分配是起了作用了,然后你的total memory还是不变的,
你还是你初始化的5M, 初始化内存和最大内存到底什么时候才会有变化呢,比如我们下面这块,一下子使用了4M,
剩余的空闲的是3M多,肯定不够了,那整个应用程序还会像我们JVM配置的max参数去申请内存,如果达到上限就可能
报内存溢出了,如果没到上限就会源源不断的JVM去申请你小于的等于MAX这个上限的,我们使用4M内存的时候,
这个时候又使用了一次GC,之前的已经回收了,经过很多次GC,老年代Tenured,前面的表示新生代的一个情况,
然后Tenured表示老年代的一个回收情况,Perm永久区回收的一个情况,然后就是用户的,系统的,真实的时常,
走完这段代码,真正的时间
我分配了4M之后
所以就看max的上限,那就会去向我的JVM发出申请,上限给我定的是20M,刚才这个来了4M,现在空闲只剩下
3M多不够了,你再给我点内存吧,那4M内存都会从MAX中申请,所以原先total memory 有5M加了4M变成了9M,
然后 free 基本不变
上面都是一些粗略的信息,然后打印两次GC,由于你配置了-XX:PrintGCDetail,我直接配置的是detail,所以他
就会把明细给我打出来,就是你堆变化的明细
eden区,from区,to区,或者叫s0区,s1区,老年代,永久区,它是怎样看使用情况的呢,我们的新生代used 5%,
老年代tenured使用了73%,因为很多数据并没有GC回收掉,永久区也会占用一些,我们主要是去看后面的一个东西,
新生代一共使用了77K,老年代使用了5587K,永久区使用了2581K