深入理解java虚拟机
2017-11-24 21:13:12 22 举报
AI智能生成
jvm学习
作者其他创作
大纲/内容
第三章
对象已死吗?
引用计数算法
可达性分析算法,GCRoots对象包括:虚拟机栈中引用的对象,方法区中类静态属性引用的对象,方法区中常量引用的对象,本地方法栈中JNI引用的对象。
强引用,软引用,弱引用,虚引用
方法区的垃圾回收,判断‘无用的类’:该类所有的实例都已经被回收,也就是java堆中不存在该类的任何实例。加载该类的ClassLoader已经被回收。该类对应的java.lang.Class对象没有在任何地方被引用,无法再任何地方通过反射访问该类的方法。是否对类进行回收,HotSpot虚拟机提供了-Xnoclassgc参数进行控制,还可以使用-verbose:class以及-XX:+TraceClassLoading(可在Product版虚拟机使用)、-XXTraceClassUnLoading(需要FastDebug版虚拟机支持)查看类加载和卸载信息。
垃圾收集算法
标记-清楚算法
复制算法
标记-整理算法
分代收集算法
第二章
jvm内存
程序计数器
字节码行号指示器
线程私有
虚拟爱规范中唯一没有OutOfMemoryError的区域
java堆
java虚拟机所管理内存中最大的一块,被所有线程共享的一块内存区域,在虚拟机启动时创建。唯一目的是存放对象实例,几乎所有对象实例都在这里分配内存
所有对象实例以及数组都要在堆上分配内存,单随着JIT发展,栈上分配,标量替换优化技术,在堆上分配变得不那么到绝对。
垃圾收集器管理的主要区域,很多时候被称作GC堆。现在收集器基本采用分代收集算法:新生代和老年代,再细致点Eden空间,From Survivor空间,ToSurvivor空间等。
可以处于物理上不连续的内存空间,逻辑连续即可。既可实现固定大小,也可扩展。如果堆中没有内存完成实例分配,并且堆无法再扩展是,将会抛出OutOfMemoryError
java虚拟机栈
线程私有,生命周期与线程相同
为虚拟机的java方法(也就是字节码)服务。java方法执行的内存模型:每个方法执行的同时都会创建一个栈帧用户存储局部变量表,操作数栈,动态链接,方法出口等。每个方法从调用到执行完成就对应着一个栈帧在虚拟机入栈到出栈的过程。
局部变量表存储:基本数据类型,引用对象,returnAddress类型。Long和double类型占用2个局部变量空间,其余的数据类型占据一个。局部变量表空间在编译期间完成分配。
栈深度大于已有深度:StackOverflowError
可扩展深度大于能够申请的内存:OutOfMemoryError
本地方法栈
为虚拟机使用到的native方法服务
StackOverflowError,OutOfMemoryError
方法区
各个线程共享的内存区域,存储已被虚拟机加载的类信息,常量,静态变量,即时编译器编译后的代码等数据。
可以选择不实现垃圾收集,这区域的内存回收目标主要是针对常量池的回收和对类型的卸载。
当方法区无法满足内存需求,OutOfMemoryError
运行时常量池
存放编译器生成的各种字面量和符号引用,直接引用。这部分内容在类加载后进入方法区的运行时常量池中存放
运行期间可以放入新的常量。当常量池无法再申请到内存时OutOfMemoryError
直接内存
NIO,使用native函数库直接分配堆外内存,通过DirectByteBuffer作为引用进行操作。如果各个内存区域总和大于物理内存的限制就会抛出OutOfMemoryError异常
hotspot对象探秘
对象的创建
对象的内存布局
对象头:对象头包含两部分信息, 一是对象本身运行数据,一是对象类型指针
实例数据:对象真正存储的有效信息,也就是代码中所定义类型的字段内容
对齐填充:起着占位符的作用
对象的访问定位
句柄访问
直接指针访问
OutOfMemory溢出实战
堆溢出:-Xms堆最小值,-Xmx堆最大值。-Xms=-Xmx避免堆自动扩展
虚拟机栈和本地方法栈溢出:-Xoss设置本地方法栈大小,(Hotspot虚拟机不区分虚拟机栈和本地方法栈)仅由-Xss设置栈大小
方法区和运行时常量池溢出:-XX:PermSize和-XX:MaxPermSize设置大小
本机直接内存溢出:-XX:MaxDirectMemorySize制定,如不指定,则默认与java堆最大值一样
0 条评论
下一页