转载

jvm系列笔记-命令行参数

两种用法:

  • 一种是使用 -cp 参数,然后传入一大堆jar包,接着传入主类,最后传入程序参数。例如:
    • java -Dkey1=val1 -Dkey2=val2 -cp a.jar:b.jar:c.jar aaa.bbb.ccc.Main arg1 arg2 arg3
    • 上述的方式中, -D 参数定义的是 系统属性 ,在java中可以通过 System.getProperty(key1) 的方式读取, arg1 arg2 arg3 定义的是程序参数,最后也就是 main 函数的 args 数组参数。
  • 第二种是使用 -jar 参数,然后传入 一个 jar包,接着就是程序参数。例如:
    java -Dkey1=val1 -Dkey2=val2 -jar xxx.jar arg1 arg2 arg3
    

顺便说一句, System.getEnv() 获取的是环境变量,就是通常意义上的进程的环境变量(jvm实质就是个进程), System.getProperty(key1) 获取的是系统属性,这个是java自己定义的一种参数, arg1 arg2 是程序参数,这个对应于main函数接收的参数。

虚拟机参数

运行模式、栈空间大小、栈帧的结构

-client -server

  • 表示虚拟机的运行模式,server模式的启动慢,但是总体运行的性能比client高,优化更多(所以热身时间长)

-Xss1024k

  • 表示线程的栈空间大小是1024k,线程的栈深度实际上是没有限制的(可能有别的限制我不知道),之所以出现StackOverflow的异常,是因为栈空间的大小达到了限制。
  • 线程栈的每个元素都是栈帧,栈帧的大小不是固定的(每个方法调用对应一个栈帧)。所以如果栈帧大,那么栈的深度就会小,栈帧小,栈的深度就会大(因为 栈空间 = 栈帧大小 * 栈深)。
  • 栈帧可以理解成一段内存,栈帧本身并不是栈式的结构,是可以在栈帧中进行随机访问的读写的。
  • 栈帧至少包含有 局部变量表操作数栈帧数据区

栈帧的结构

局部变量表

就很简单,我们的方法的参数、方法里面声明的局部变量,都存在局部变量表里。局部变量中,会有一堆插槽,一个插槽可以放一个数据(一个byte、一个char、一个short...等,以及一个reference)。虚拟机通过插槽索引来使用局部变量表里的数据(比如说引用插槽0,可能对应一个数字3,引用插槽2,可能对应一个对象的引用)

操作数栈

操作数栈是栈帧里的一个栈(就是说,栈帧里有好几块不同的区域,其中一块区域作为一个栈来使用了,就是操作数栈)。主要是用来保存计算的中间结果,以及作为计算过程中变量的临时存储空间(因为一些指令操作的模式都是入栈出栈然后计算)。

帧数据区

栈帧除了上面的数据之外,还需要一些数据来支持常量池解析,方法返回和异常处理等。比如我们返回值存放在哪里,异常处理表存放在哪里,这些都需要放在帧数据区,jvm还可以实现一些别的数据区存放在这里。

原文  https://juejin.im/post/5d898610518825090f4199e1
正文到此结束
Loading...