JDK是用于支持Java程序开发的最小环境
Java Development kit
JDK--包含-JRE--包含--JVM
JRE(包含JAVASEapi和JVM虚拟机)
参数 说明
-XX:+HeapDumpOnOutOfMemoryError 内存溢出时自动导出内存快照
-XX:HeapDumpPath=E:/dumps/ 导出内存快照时保存的路径
运行时数据区域
方法区----虚拟机栈----本地方法栈
堆--------------------程序计数器
程序计数器:他可以看做是当前线程锁执行的字节码信号指示器,在逊尼基的概念模型中,字节码解释器的工作是通过改变计数器
的值来选取下一个字节码的指令,分支,循环,跳转,异常处理,线程恢复等基础功能都依赖程序计数器。线程私有的内存
如果线程正在执行的是一个java方法,这个计数器记录的是正在整形的虚拟机字节码指令的地址,如果native方法计数器空
java虚拟机栈 也是线程私有的,虚拟机栈面熟的额是java方法执行的内村模型。每个方法被执行的时候会同事常见一个栈帧,用于存放
局部变量表,操作站,动态链接,方法出口等信息。
局部变量表存放编译器可知的各种基本数据类型(boolean,byte,char,short,int,float,long,double),对象引用 和returnaddress;
类型(一条字节码指令的地址)
其中64位长度的long和double站两个局部变量空间其余一个,局部变量表的内存空间在编译期间完成分配
本地方法栈:虚拟机栈是执行java方法(也就是字节码)服务,本地方站则是为虚拟机使用到native方法服务。
java堆:存放对象实例,是所有线程共享的一块内存区域,在虚拟机启动时候常见,几乎所有的对象实例都会在哎这里分配内存,也叫GC堆
是内存回收的角度看,现在的收集器都是采用分代手机算法,所以java堆分为新生代和老年代
再细分为Eden空间,from survivor空间(持久区),to urvivor空间(永久区) 可通过-Xmx -Xms控制堆把内存,无法扩展时抛出outfomemoryerror异常
方法区:与java堆一样,是各个线程共享的内存区域,用于存储一直的类信息,常量,静态变量,即时编译器变异后的代码
这个区域的内存回收目标主要针对常量池的回收和对类型的卸载,这个区域的回收比较难以令人满意
运行时常量池:是方法区的一部分,Class文件除了有类的版本,字段,方法,接口等描述信息,还有常量池,用于存放编译器生成的字面量和符号音乐,在类加载的
时候存放到方法区的常量池中。
而运行时常量池,则是jvm虚拟机在完成类装载操作后,将class文件中的常量池载入到内存中,并保存在方法区中,我们常说的常量池,就是指方法区中的运行时常量池。
运行时常量池相对于CLass文件常量池的另外一个重要特征是具备动态性,Java语言并不要求常量一定只有编译期才能产生,也就是并非预置入CLass文件中常量池的内容才能进入方法区运行时常量池,运行期间也可能将新的常量放入池中,这种特性被开发人员利用比较多的就是String类的intern()方法。
String的intern()方法会查找在常量池中是否存在一份equal相等的字符串,如果有则返回该字符串的引用,如果没有则添加自己的字符串进入常量池。
常量池的好处
常量池是为了避免频繁的创建和销毁对象而影响系统性能,其实现了对象的共享。
例如字符串常量池,在编译阶段就把所有的字符串文字放到一个常量池中。
(1)节省内存空间:常量池中所有相同的字符串常量被合并,只占用一个空间。
(2)节省运行时间:比较字符串时,==比equals()快。对于两个引用变量,只用==判断引用是否相等,也就可以判断实际值是否相等。