JVM看多次都是容易忘,写此博客来记录自己的所学
内存区域划分为线程共享和独立两大部分,线程共享的区域为:方法区、堆、执行引擎和本地方法库;线程独立的:虚拟机栈、本地方法栈和程序计数器
线程独立区域
1、程序计数器:是一块较小的内存空间,可以看着是当前线程所执行的字节码的行号指令
2、虚拟机栈:它的生命周期和线程相同,它描述的是Java方法执行的内存模型,每个方法执行的同时都会创建一个栈帧用于存储局部变量、操作数栈、动态链接、方法出口等信息。这个区域规定了两种异常:如果线程请求的栈深度大于虚拟机所允许的深度,将抛出StackOverflowError;如果虚拟机栈可以动态扩展,如果扩展时无法申请到足够的内存,就会抛出OutOfMemoryError
3、本地方法栈:与虚拟机栈所发挥的作用非常相似,他们之间的区别不过是虚拟机栈执行Java方法服务,而本地方法栈则为虚拟机使用到的native方法服务。和虚拟机栈一样也会抛出StackOverflowError和OutOfMemoryError异常
线程共享区域
1、Java堆:是Java虚拟机所管理的内存中最大的一块,是被所有线程共享的一块内存区域,在虚拟机启动时创建。此区域的唯一目的就是存放对象实例,几乎所有的对象实例都在这里分配内存。Java堆是垃圾收集器管理的主要区域。Java堆可以细分为新生代和老年代;再细致点有Eden空间、From Survivor空间、To Survivor空间等(-Xmx最大堆大小和Xms最小堆大小控制扩展)。Java堆中可能划分出多个线程私有的分配缓冲区(Thread Local Allocation Buffer,TLAB)。
2、方法区:用于存储已被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码数据等。
3、运行时常量池:它是方法区的一部分。Class文件中除了有类的版本、字段、方法、接口等描述信息外,还有一项常量池,用于存放编译期生成的各种字面量和符号引用,这部分内容将在类加载后进入方法区的运行时常量池中。
4、直接内存并不是虚拟机运行时数据区的一部分,也不是Java虚拟机规范中定义的内存区域。但是这部分也被频繁使用,而且也可能导致OutOfMemoryError
-Xmx:设置堆的最大大小 -Xmx200m
-Xms:设置堆的最小大小 -Xms20m
-Xss:设置栈的大小 -Xss512k
-XX:PermSize设置方法去的容量大小 -XX:PermSize=10m
-XX:MaxPermSize设置方法去的最大容量大小 -XX:MaxPermSize=20m
-XX:+HeapDumpOnOutMemoryError 让虚拟机在出现内存溢出时Dump出当前内存堆转存快照