jvm 虚拟机分为
一、虚拟机
1.程序计数器
记录当前jvm正在执行的虚拟机字节码指令的地址(各个线程独立持有)
2.java 虚拟机栈
线程私有,生命周期和线程相同 ,方法中的所有new 对象存储在堆上,每个方法执行会创建一个栈帧用于存储局部变量表、操作数栈、动态链接、方法出口等信息。每一个方法从调用直至执行结束,就对应着一个栈帧从虚拟机栈中入栈到出栈的过程
局部变量表:存放了编译期可知的各种基本类型(boolean、byte、char、short、int、float、long、double)、对象引用(reference 类型)和 returnAddress 类型(指向了一条字节码指令的地址)
这也是为什么方法中 对于传参是对象类型的改变 外层可以拿到,但是基本类型传参的改变 ,外层拿不到
3.本地方法栈
本地方法栈则为虚拟机使用到的 Native 方法服务。也会有 StackOverflowError 和OutOfMemoryErro 异常(部分虚拟机如Sun HotSpot虚拟机会将 java虚拟机栈和本地方法栈合二为一)
4.Java堆
所有线程共享区域、存放对象实例 是GC的主要区域、堆可以处于物理不连续内存区域(逻辑连续即可)
堆又分为 新生代(Eden+From Survivor+To Survivor)和老年代 (OldGen)如下
5.方法区(永久代)
所有线程共享区域、存储虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等数据 ,方法区逻辑上为堆一部分,但是为了区分,一般把它不划分在堆名义上,(JDK 1.8融合HotSpot JVM与 JRockit VM废除了永久代,移到直接内存中)
6.运行常量池
方法区一部分,用于存放编译期生成的各种字面量和符号引用,类加载后存放于方法区的运行时常量池中
7.直接内存
直接内存并不是jvm虚拟机运行的一部分,也不是jvm虚拟机规范种定义的内存区域
JDK 1.4 中新加入 NIO (New Input/Output) 类,引入了一种基于通道(Channel)和缓存(Buffer)的 I/O 方式,它可以使用 Native 函数库直接分配堆外内存,然后通过一个存储在 Java 堆中的 DirectByteBuffer 对象作为这块内存的引用进行操作。可以避免在 Java 堆和 Native 堆中来回的数据耗时操作。不受jvm 内存影响,但受机器内存影响(废话:所有跑在机器上需要内存的肯定都受机器内存影响)
二、参数说明
参数 | 说明 |
---|---|
-Xmx = 1024m | 堆内存的最大值 |
Xms = 1024m | 初始堆内存大小(最小堆内存) |
-XX:NewSize = 256m | 新生代的最小内存值 |
-XX:NewMaxSize = 256m | 新生代的最大内存值 |
-XX:NewRatio = 1:2 | 设置新生代与老年代的比值 |
-XX:SurviorRatio = 4:1 | 设置Eden与Survivor的比值 |
-XX:TargetSurvivorRatio = 50 | 设置Survivor的使用率 |
-XX:MaxTenuringThreshold = 15 | 进入老年代的阀值 |
-XX:MaxPermSize = 256m | 方法区的最大值 |
-XX:PermSize = 128m | 方法区的最小值 |