深入理解JVM(学习过程) (23)

引用指向的对象并不是目标本身,而是一个指针指向对象的实例数据,另一个指针指向方法区中的类型数据(元数据)。如图 所示。Oracle的JVM采用下方的引用方式(使用直接指针的方式)。

使用句柄的好处(引用永远指向他,引用不会跟着修改)

直接指针的好处(在压缩的时候效率比句柄的方式更高)

image-20200216055201640

Java对象内存分配原理与布局 /** 关于Java对象创建的过程: new 关键字创建对象的3个步骤: 1. 在堆内存中创建出对象的实例。 2. 为对象的实例成员变量赋初值。(调用init方法,进行初始化) 3. 将对象的引用返回。(将结果返回给栈帧) 对象存储的两种方式(出现两种情况的原因与垃圾收集器密不可分): 1. 指针碰撞:(前提是堆中的空间通过一个指针进行分割,一侧是已经被占用的空间,另一侧是未被占用的空间) 2. 空闲列表:(前提是堆内存空间中已被使用与未被使用的空间是交织在一起的,这时虚拟机就需要通过一个列表来记录哪些空间是已被使用的,哪些空间是未被使用的,接下来找出可以容纳下新创建对象的且未被使用的空间,在此空间存放该对象,同时还要修改列表上的记录) 对象在内存中的布局: 1. 对象头 2. 实例数据(即我们在一个类中所声明的各项信息,成员变量的信息) 3. 对齐填充(可选) 引用访问对象的方式: 1. 使用句柄的方式。 好处:(引用永远指向他,引用不会跟着修改) 2. 使用直接指针的方式。(Oracle的JVM使用的方式) 好处:(在压缩的时候效率比句柄的方式更高) */ 堆溢出、栈溢出、方法区溢出实例练习 堆溢出举例,实战jvisualvm // 堆溢出举例 (CPU会起飞) public class MyTest1{ psvm{ List<MyTest1> list = new ArrayList(); for( ; ; ){ list.add(new MyTest()); // System.gc(); // 不建议日常开发中使用。垃圾回收:运行垃圾回收器。虚拟机去尝试回收不再使用的对象。此时就不会报错了,正是由于这一行代码起作用,进行垃圾收集了。 } } } // 在 vm options中添加参数: -Xms5m -Xmx5m -XX:+HeapDumpOnOutOfMemoryError // 设置堆内存为5M ,打印出堆溢出的转储文件

image-20200216065542670

对应的JVM的运行信息:类,实例数等信息都可以在这里通过工具查看。

截屏2020-02-16上午7.01.28

我这里jdk8带的jvisualvm打不开,没有跟着练习看一下。

image-20200216082653541

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wpfdfy.html