java中的内存分配和释放都是由jvm自动完成,那么为什么还要学习这块呢,当发生内存泄露和内存溢出,当系统并发量过大导致垃圾回收遇到了瓶颈时,就需要对这种自动化的技术加以监控和调节
对象和引用
对象存在于堆中,而引用存在于栈中,通常在对象被创建以后,我们使用的是引用来对对象进行操作。如代码片段Object obj= new Object (),右边new Object ()在堆上创建了一个对象,左边Object obj则是创建了一个名为obj的引用,“=”号的意义是,obj的引用指向new Object ()在堆上创建的对象。当obj= null时,obj引用就指向空,也就是从指向new Object ()创建的对象变为不指向任何对象。obj引用也可以再次指向其他的对象。总的来说,引用是一种比较灵活的描述对象的手段,引用可以随时任意地改变指向的对象。
对象的访问定位
那怎么去通过引用来操作对象呢?目前主流的通过引用访问对象的方式:通过句柄访问对象和直接通过指针去访问对象
通过句柄去访问
堆中会划分出一片内存来作为句柄池,引用(reference)中存储的就是句柄地址,而句柄中包含了对象实例数据与类型数据各自的具体地址信息,如下图
好处是在对象被移动的时候(如垃圾回收),只会改变句柄中的地址信息,而不会改变引用
通过指针直接访问
sun hotpot使用的则是这一种方式,引用直接存储的是对象的地址信息,因此速度更快更高效,毕竟少了一个句柄的中间环节,如下图。
zhizhen.png引用的类型
引用分为四种类型,强度依次减弱
- 强引用 代码中普遍存在的一种引用,如Object obj= new Object ()中的obj就是强引用,只要强引用还存在,被引用的对象就不会被垃圾回收器回收
- 软引用 用来描述非必需对象的,在系统发生内存溢出异常之前,才会回收软引用,可通过SoftReference来实现软引用
- 弱引用 也是描述非必需对象的,强度比软引用还弱,当发生垃圾收集时,会回收弱引用关联的对象,可用weakReference实现弱引用,ThreadLocal的实现就使用了弱引用
- 虚引用 最弱的一种引用,一个对象是否有虚引用的存在对对象的生存时间毫无影响,也无法通过虚引用来获取一个对象实例。虚引用唯一的作用就是虚引用关联的对象被回收时能够受到一个系统通知,可用PhantomReference来实现
网友评论