2.1 java 内存区域

运行时数据区中,左边为线程共享区域,右边为线程私有
2.1.1,程序计数器
内存小,线程私有。该区域没有OOM
执行java方法时,记录正在执行的虚拟机字节码指令地址。
Native方法时,计数器的值为undefined。
字节码解释器通过改变这个计数器的值来选取下一条需要执行指令的字节码指令。
2.1.2,虚拟机栈 stack
线程私有,生命周期与内存一致。Stack Overflow Error , OOM
每一个方法从调用直至执行结束,就对应着一个栈帧从虚拟机栈中入栈到出栈的过程。
栈帧用于存储局部变量表,操作数栈,动态链接,方法出口等
局部变量表存放编译期可知的基本类型(boolean、byte、char、short、int、float、long、double)
对象引用保存在堆栈里
2.1.3,本地方法栈
区别于虚拟机栈,虚拟机栈为执行java方法(字节码)服务,本地方法栈为native方法服务。
2.1.4, java堆 heap
内存最大,线程共享,存放对象和数组,物理上可以连续的空间,逻辑上连续,有OOM
所有Java 对象都保存在里面
由jvm的垃圾回收器来管理
String str1 = new String("abc"); 每次都生成一个对象
2.1.5,方法区
线程共享,存放类信息,常量,静态变量,即时编译后的代码
运行时常量池,方法区的一部分,编译期生成的字面量,符号引用。
运行期String.intern() 可以将常量池放入池内, 有OOM
2.1.6直接内存
非虚拟机部分。nio 引入了基于Channel和Buffer的I/O,可以使用native分配堆外内存,由存在java 堆中的DirectByteBuffer对象作为该引用来操作。有OOM
2.2 垃圾回收
程序计数器,虚拟机栈,本地方法栈随线程生灭(线程私有)。
而java堆和方法区,程序在运行时才知道有哪些对象会创建,内存的分配和回收都是动态的。
对象已死?
引用计数法,对象中添加一个引用计算器,引用它时加1,失效时减。 无法解决循环引用问题。
可达性分析法,‘GC Roots’ 的对象作为起始点,从这些节点出发所走过的路径称为引用链。当一个对象到 GC Roots 没有任何引用链相连的时候说明对象不可用。
不可达的对象,还暂时在“缓刑”阶段,没有与GC roots 引用链时,会被第一次标记并筛选:
[if !supportLists]1,[endif]没有覆盖finalize();2,finalize()已经被虚拟机调用过。都视为‘没有必要执行’。
执行finalize时还有最后一次逃离机会,只要重新与引用链上的任何一个对象简历关联即可。
回收方法区
永久代垃圾回收的主要俩个部分,废弃的常量和无用的类。
引用强度
强引用,
软引用(系统要发生内存溢出之前),
弱引用(下一次垃圾收集之前),
虚引用无法获取对象实例,只为收到回收时的系统通知
2.3类加载机制
虚拟机把描述类的数据从Class文件加载到内存,并对数据进行校验、装换解析和初始化,最终形成可以被虚拟机直接使用的 Java 类型。
加载、连接和初始化过程都是在程序运行期间完成的。
网友评论