`

对象访问分析

    博客分类:
  • JVM
JVM 
阅读更多
对象引用及对象赋值


一、对象引用与对象创建

Object obj = new Object(); 


  • Object:类对象,存放在方法区中
  • Object obj:类引用变量,即类的实例对象的引用,存放在Java虚拟机栈中的局部变量表
  • new Object:形成了一块存储了Object类型所有实例数据值(对象中各实例字段的值数据)的结构化内存,存放在堆区
  • ():类对象中构造方法,対生成的对象进行初始化;类对象中一定有构造方法,系统默认提供无参的构造方法,如果现实声明其他构造方法,则系统不提供默认的构造方法
  • =:操作符使对象引用指向刚创建的那个Object对象,即 obj 中存放 new Object() 在堆中的空间的首地址


Object obj = null ; // ojb 对象引用指向 null
obj = new Object(); // obj 对象引用指向 新对象
Object obj1 = obj ; // 此时 obj obj1 指向都一个对象

对象引用与对象的关系
  • 一个对象引用可以指向0个或1个对象(即对象引用可以指向null)
  • 一个对象可以有N个引用指向它(即对象引用存放的同一个对象在堆中的空间的首地址)
  • 通过一个对象的引用来对对象进行操作


// obj 原来指向 new Object();若此时 obj1 = null ;
// 那么当  obj 指向新对象后,原来的无引用指向的 new Object()
// 将会成为垃圾回收机制的处理对象,何时回收由GC控制
obj = new ObjectOther(); // 再次为 obj 赋值,指向其他对象
System.out.print("abc") ; // 匿名字符串对象
System.out.print(new A().getA()); // 直接使用匿名对象中的方法

  • 临时对象:对象与引用的关系将持续到对象回收。如:匿名对象



二、reference类型对象的引用有两种方式

1.句柄池

堆中将划出一块内存作为句柄池,reference中存储的是对象的句柄地址,而句柄中包含了对象实例数据和类型数据各自的具体地址信息

2.直接引用

reference中直接存储的就是对象地址,对象地址存有指向方法区中类型数据的地址信息

3.
句柄的最大好处就是GC时,对象被移动时只需要改变句柄的实例数据指针;而reference不用修改
直接指针访问方式则速度快,节省了一次指针定位的时间,因对象访问在Java中非常频繁,故很有利,虚拟机Sun Hot Spot 就采用此方式

三、方法传参

参数为值传递,而不是引用传递;
对于基本数据类型,传递的是数据本身的值;
对应引用数据类型,传递的是对象的引用,即存放在堆中的地址值;

package com.java.study.test.unit8;

public class ParameterMethodMain {

	private Integer i ;
	
	private Integer j ; 

	private ParameterMethodMain(){
		super();
	}
	
	private ParameterMethodMain(Integer i ,Integer j){
		this.i = i ;
		this.j = j ;
	}
	
	/**
	 * @param args
	 */
	public static void main(String[] args) {
		
		// 1.基本数据类型,方法中传递的是值本身
		// 方法中对值的修改不影响原来值的大小;
		// 重新赋值:即改变原来的变量的内容,才会改变原来值的大小
		// int 对应包装类 Integer ,Integer 为 final 修饰,同 String ,不可改变
		int a = 0 ;
		changeMethodBasic(a);
		System.out.println(a); // 0
		a = changeMethodBasic(a);
		System.out.println(a); // 100 
		
		// 2.引用数据类型
		ParameterMethodMain main = new ParameterMethodMain();
		main.setI(1);
		main.setJ(2);
		// 传递的是对象数据类型的引用,指向同一个堆中的对象,
		// Main()方法中的 main对象引用与方法中的main引用指向了同一个对象
		// 所以对象的改变是共享的
		changeMethodRefence(main);
		System.out.println("i="+main.getI()+" j="+main.getJ());// i=3 j=4
		// changeMethodRefenceNew 中的参数  ParameterMethodMain main 
		// 只是接收了Main()中main对象引用传递的对象的地址,而与main对象无关系
		// 在changeMethodRefenceNew 中对形参main进行重新赋值,与Main()方法中的main对象无关
		// 此处仅仅是命名相同而已
		changeMethodRefenceNew(main);
		System.out.println("i="+main.getI()+" j="+main.getJ());// i=3 j=4
		// 改变了当前对象指向的内容,指向了新的对象
		// 强制改变了Main()方法中main对象的引用中存放的地址
		main = changeMethodRefenceNew(main);
		System.out.println("i="+main.getI()+" j="+main.getJ());// i=5 j=6

		// 3.String 是引用数据类型,但很特殊,因为String 的特点是对象不可变;
		// 任何对已有的string对象的引用的操作都会产生新的对象
		String str = new String("abc") ;
		// changeStr 方法中的形参 String str 接收Main()方法中str的对象引用地址的传递
		// changeStr 中对str重新赋值,实际是新生成了一个对象bcd,并将str指向了bcd对象
		// 但changeStr 中仅仅是方法内部生效
		changeStr(str);
		System.out.println(str);
		// 相当于Main()的 str 重新赋值,指向新的对象的地址
		str = changeStr(str);
		System.out.println(str);
		
	}

	public static int changeMethodBasic(int a){
		System.out.println("a="+a); // a=0
		a = 100 ;
		System.out.println("a="+a); // a=100
		return a ;
	}
	
	public static void changeMethodRefence(ParameterMethodMain main){
		main.setI(3);
		main.setJ(4);
	}
	
	public static ParameterMethodMain changeMethodRefenceNew(ParameterMethodMain main){
		ParameterMethodMain newMain = new ParameterMethodMain();
		newMain.setI(5);
		newMain.setJ(6);
		main = newMain;
		return main;
	}
	
	public static String changeStr(String a){
		a = "bcd";
		return a ;
	}
	
	
	
	public Integer getI() {
		return i;
	}

	public void setI(Integer i) {
		this.i = i;
	}

	public Integer getJ() {
		return j;
	}

	public void setJ(Integer j) {
		this.j = j;
	}
}


  • 方法中传递参数,值传递而非引用传递
  • 对于引用数据类型,方法中的形参是对调用位置传入的引用地址的拷贝,相当于同时又多了一个指向此对象的对象引用,所以方法中的形参修改对象时,影响调用此方法中的对象;但交换地方、重新指向新对象都不会影响调用方法中的对象,即相当于方法中的对象引用断开了与此对象间的绑定关系,但与调用方法中的对象引用无关
  • 对于String,是引用数据类型,但String本身的特点是对象不可变,方法中的形参接收到传递的引用地址,对对象的修改都会产生新的String对象,也就是形参中的对象引用指向了新的对象
  • 对于基本数据类型,传递的值


四、引用

索引强度:强引用 > 软引用 > 弱引用 > 虚引用,与GC有关

对比强引用软引用弱引用虚引用
英文Strong ReferenceSoftReferenceWeakHashMapPhantomRefrence
GC尽可能长时间的存活于 JVM 内, 当没有任何对象指向它时 GC 执行后将会被回收最大的区别在于 SoftReference 会尽可能长的保留引用直到 JVM 内存不足时才会被回收(虚拟机保证), 这一特性使得 SoftReference 非常适合缓存应用当所引用的对象在 JVM 内不再有强引用时, GC 后 weak reference 将会被自动回收;在垃圾回收器线程扫描它所管辖的内存区域的过程中,一旦发现了只具有弱引用的对象,不管当前内存空间足够与否,都会回收它的内存建立虚引用之后通过get方法返回结果始终为null,通过源代码你会发现,虚引用通向会把引用的对象写进referent,只是get方法返回结果为null;在任何时候都可能被垃圾回收器回收
作用-使用软引用构建敏感数据的缓存-虚引用主要用来跟踪对象被垃圾回收器回收的活动;当垃圾回收器准备回收一个对象时,如果发现它还有虚引用,就会在回收对象的内存之前,把这个虚引用加入到与之 关联的引用队列中,程序可以通过判断引用队列中是否已经加入了虚引用,来了解被引用的对象是否将要被垃圾回收。如果程序发现某个虚引用已经被加入到引用队列,那么就可以在所引用的对象的内存被回收之前采取必要的行动
ReferenceQueue--可选必须配合使用
定义就是指在程序代码中普遍存在的,类似Object obj = new Object()这类的引用,只要强引用还存在,垃圾收集器永远不会回收掉被引用的对象是用来描述一些还有用但并非必须的对象。对于软引用关联着的对象,在系统将要发生内存溢出异常之前,将会把这些对象列进回收范围之中进行第二次回收。如果这次回收还没有足够的内存,才会抛出内存溢出异常用来描述非必须的对象,但是它的强度比软引用更弱一些,被弱引用关联的对象只能生存到下一次垃圾收集发送之前。当垃圾收集器工作时,无论当前内存是否足够,都会回收掉只被弱引用关联的对象。一旦一个弱引用对象被垃圾回收器回收,便会加入到一个注册引用队列中。虚引用也称为幽灵引用或者幻影引用,它是最弱的一种引用关系。一个持有虚引用的对象,和没有引用几乎是一样的,随时都有可能被垃圾回收器回收。当试图通过虚引用的get()方法取得强引用时,总是会失败。并且,虚引用必须和引用队列一起使用,它的作用在于跟踪垃圾回收过程


五、对象可达性的判断

  • 对象引用关系:按照对象被谁引用,被一个或多个对象引用,组成已根级为顶点的树状结构;而不是以当前对象引用了哪个对象去统计
  • 单条引用路径可达性判断:在这条路径中,最弱的一个引用决定对象的可达性。
  • 多条引用路径可达性判断:几条路径中,最强的一条的引用决定对象的可达性。


举例:
箭头的方向代表了引用的方向,所指向的对象是被引用对象
A-->B-->C-->D
A-->E-->F-->D
B-->C强引用,C-->D弱引用,B-->C-->D弱引用
E-->F强引用,F-->D软引用,E-->F-->D软引用
D对象是软引用

博文参考:
Java引用类型
深入理解StrongReference,SoftReference, WeakReference和PhantomReference
对象访问分析
浅谈java对象引用及对象赋值
分享到:
评论

相关推荐

    面向对象的系统分析与设计 课件+课后答案

    面向对象的系统分析与设计是计算机科学领域中的一个重要主题,它涵盖了软件开发过程中的一些关键概念和技术。本资源包括了相关的课件和课后答案,帮助学习者深入理解这一主题。以下将详细介绍其中涉及的主要知识点:...

    面向对象的分析方法---学习

    1. **对象唯一性**:每个对象都有一个独一无二的标识,确保在整个生命周期内可以唯一地识别和访问。 2. **分类性**:分类性允许我们通过抽象将具有相同属性和行为的对象归类为一类,简化了模型的复杂性。 3. **...

    面向对象系统分析与设计

    5. **封装**:封装是隐藏对象的属性和实现细节,只对外提供公共访问方式。它保护了数据的安全性,减少了错误发生的可能性,同时提高了代码的模块化。 6. **设计模式**:在面向对象设计中,设计模式是一种解决常见...

    深入浅出面向对象分析与设计.pdf

    1. **封装**:封装是指将数据(属性)和操作这些数据的方法(行为)组合在一个独立的对象中,并对外部隐藏其内部细节,只提供外部可以访问的接口。 2. **继承**:继承允许创建一个类(子类)继承另一个类(父类)的...

    面向对象分析与设计(第3版).pdf

    面向对象分析与设计(第3版):深入解析与应用 《面向对象分析与设计(第3版)》是一本专注于面向对象编程方法论的重要教材,尤其针对Java开发者提供了详尽的指导。本书通过深入浅出的方式,不仅阐述了面向对象的...

    面向对象分析与设计

    面向对象分析与设计是软件开发过程中至关重要的环节,它涵盖了从需求理解到系统构建的一系列步骤,以提高软件的质量和可维护性。本知识体系主要围绕五个核心主题展开:方法、重构、模式、概念和原则。 首先,让我们...

    华农面向对象分析与设计试卷

    面向对象分析与设计是软件开发过程中的核心环节,它涵盖了如何使用面向对象的思维方式来理解和表述问题领域,以及如何设计出高效、可维护的软件系统。在这个领域,我们主要涉及三个关键概念:对象、类和继承,以及...

    第六章结构化分析和第七章面向对象分析.pdf

    继承和泛化是实现代码重用和层次化设计的机制,而封装则通过信息隐蔽技术限制了对象内部状态的访问。面向对象分析的过程中,注重寻找对象、确定对象的属性和方法、组织类的设计,并通过动态模型和交互次序的图形化...

    面向对象分析与设计课程结课大作业.pdf

    协作图则关注对象间的交互关系,强调它们如何协同工作,如修改用户信息时,用户、数据库访问层和存储数据库之间的交互。 4. **状态图建模**: 状态图描绘了对象在其生命周期内可能经历的不同状态及其转换。用户...

    面向对象分析与设计OOAD课件(北大青鸟内部培训课件)

    面向对象分析与设计(Object-Oriented Analysis and Design,简称OOAD)是软件工程领域中的一种重要技术,它主要用于构建复杂、可维护的软件系统。本课件是北大青鸟内部培训材料,全面且深入地讲解了面向对象的理论...

    面向对象分析设计参考案例-网上书店系统WebLab

    ### 面向对象分析设计参考案例:网上书店系统WebLab #### 一、面向对象的概念及重要性 面向对象编程(Object-Oriented Programming,简称OOP)是一种软件开发方法,它通过“对象”这一基本单位来组织代码。对象是...

    北航软件学院面向对象分析与设计课后作业

    面向对象分析与设计是软件工程领域中一个至关重要的部分,特别是在高等教育阶段,如北京航空航天大学软件学院的教学中,这一主题占据了核心地位。谭火彬老师的课程致力于培养学生的面向对象思维和设计能力,以便他们...

    《面向对象分析与设计》(UML 2.0版)

    它通过访问控制(如public、private和protected)来保护对象的内部状态,防止外部代码随意修改。 3. **多态性**:多态性是指同一种行为可以有不同的表现形式,具体取决于对象的类型。它允许我们使用一个接口来调用...

    面向对象分析与设计 grady著 中文版(第三版)

    根据提供的文件信息,有关《面向对象分析与设计 Grady 著 中文版(第三版)》的知识点将围绕面向对象分析与设计(Object-Oriented Analysis and Design, 简称OOAD)的主要概念进行详细说明。由于提供的部分内容重复...

    javascript面向对象之访问对象属性的两种方式分析.docx

    ### JavaScript面向对象之访问对象属性的两种方式分析 #### 一、引言 在JavaScript中,面向对象编程是一种常见的编程范式,它可以帮助开发者更好地组织和管理代码。访问对象属性是面向对象编程中最基本的操作之一...

    面向对象分析与设计试题与答案

    面向对象分析与设计是软件开发中的重要方法,它基于对象的概念,强调数据和操作数据的方法紧密结合,以提高软件的可重用性和可维护性。本题集主要考察面向对象编程的基础知识,包括语言特性、面向对象原则、类与对象...

Global site tag (gtag.js) - Google Analytics