JVM内存结构入门篇
什么是JVM?
java virtual machine
java 虚拟机
JRE -> JDK ->JVM
程序计数器
线程私有,用于记住jvm下一条执行指令的地址
java代码的运行过程
java源代码通过javac命令编译成二进制字节码文件,二进制字节码文件通过解释器编译成机器码交给cpu执行
特点
- 线程私有,cpu通过时间片进行分配调度
- 不会存在内存溢出
本地方法栈
本地方法栈用于给本地方法提供内存空间,本地方法:使C语言或C++编写方法,在java使用native修饰
虚拟机栈
栈:一种数据结构,先进后出
在java中,虚拟机栈是线程运行的空间,而一个栈由多个栈帧组成;栈帧对应着java中的方法运行所需要的内存空间,每个线程只能由一个活动栈帧(栈顶部对应的栈帧),对应着正在执行的方法;
查看活动栈帧通过idea的Debug方式进行查看
特点
虚拟机栈中不存在垃圾回收,因为当我们的方法运行结束之后,栈内存会弹出栈帧,释放空间,即方法被销毁;如果使用特殊的方式(递归等方式)造成栈内存溢出,程序会抛出StackOutOfMemoryError
注意:
栈内存不是越大越好,而是根据内存和实际开发情况而定,假设现有内存500M,每个虚拟机栈内存占用1M,在理想环境下可以并发运行500个线程,如果此时将栈内存调节至5M,那么此情况下,最多能运行100个线程,效率明显降低了。所以栈内存的调节要根据内存以及实际开发情况
堆
定义
- 通过new关键字创建的对象都会使用堆内存
特点
- 线程共享,堆内存中对象都需要考虑线程安全问题
- 存在垃圾回收
方法区
定义
所有虚拟机线程所共享的一个区域,它存储着类结构的相关信息;包括成员方法,构造方法,特殊方法以及运行时常量池;方法区在虚拟机启动时创建,逻辑上是堆的组成部分;在jdk1.8之前,方法区的实现是通过堆中的永久代实现,在jdk1.8之后,方法区的实现是通过元空间来实现
内存溢出
-
1.8之前会导致永久代内存溢出
Java.lang.OutOfMemoryError:PermGen space
-XX:MaxPermSize = 8m
-
1.8之后会导致元空间内存溢出
Java.lang.OutOfMemoryError:Metaspace
-XX:MaxMetaspaceSize = 8m