JVM内存结构
jdk包含jre,jre包含jvm.
jdk是一个合集,包括一些编译工具
jre是Java运行环境,包含一些插件
jvm是最基础的,做翻译的,将class翻译成操作系统是的指令(0101)
2.运行时数据区
线程私有:程序计数器、虚拟机栈、本地方法栈
线程共享:堆、方法区
程序计数器(唯一不会OOM的区域):记录指向当前线程正在执行的字节码指令的地址(行号)
Java是多线程的,意味着线程切换,确保多线程情况下的程序正常执行。
栈(stack):一种数据结构
为什么jvm要使用栈?答:更好的兼容方法调用方法的特点。
虚拟机栈(大小设置 -Xss 1M,虚拟机栈就是在栈数据结构上的一个种拓展):存储当前线程运行方法所需的数据,指令、返回地址
栈帧:多个方法,每个方法就是一个栈帧
方法转换为字节码,在虚拟机中运行过程
栈默认大小为1M,StackOverFlowError(栈溢出)的出现是因为方法死递归调用本方法,导致内存超出1M。
OOM栈内存溢出,很多线程在跑,10万个线程栈空间就是10万*1M,导致内存不足。
本地方法栈:是保存的native方法信息,jvm调用后,jvm不为其在虚拟机中创建栈帧,jvm只是简单动态并直接调用native方法。
方法区(永久代jdk1.7及以前,元空间jdk1.8):存放类信息、常量(final)、静态变量(static),即时编译的代码(js)
永久代参数:-XX:PermSize;-XX:MaxPermSize
元空间参数:-XX:MetaspaceSize; -XX:MaxMetaspaceSize;
堆(-Xms;-Xmx;-Xmn):关注内存的分配(new关键字,反射等)与回收(回收算法,收集器等)。运行时常量池,变量(int)实例变量,没有final、static修饰的变量。几乎所有对象都在堆中分配
运行时常量池:在堆中,字符引用、字面量(String a = “123”, 123为字面量)
元空间和永久代的区别?
元空间只受限于机器内存,可以无限扩容。永久代受制于堆。
直接内存:jvm规范里面没有规定。
NIO使用本地内存