| |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
-> Java知识库 -> 学习-Java类和对象之对象引用之坐标系中两点距离计算 -> 正文阅读 |
|
[Java知识库]学习-Java类和对象之对象引用之坐标系中两点距离计算 |
任务描述 本关任务:已知两个点 A、B 以及坐标分别为(2,3) 、(8,-5) ,求 A 和 B 两点之间的距离。 两点间的距离计算公式:设两个点A、B以及坐标分别为(x1?,y1?)、(x2?,y2?),则A和B两点之间的距离为:∣AB∣=(x1??x2?)2+(y1??y2?)2?。 相关知识 为了完成本关任务,你需要掌握:
对象的引用和对象 首先我们来看一个例子:
接下来,我们用 Demo 类来创建一个对象。
我们来对这条语句进行一个解析:
当然这条语句我们也可以写成:
对象与引用的关系:
引用只是存放一个对象的内存地址,并非存放一个对象, 就好比钥匙与房子的关系,钥匙相当于引用,房子相当于对象,钥匙只是能打开房子,而并非就是一个房子。创建一个引用对象就是创建一把钥匙而并非是造了一个房子。 对象的比较 在 Java 之中不仅仅存在两个数字与两个字符串之间的比较,还存在两个对象之间的比较。 众所周知,两个数字之间的比较我们使用“==”,两个字符串之间的比较我们使用“equals()”,那么两个对象之间如何进行比较呢?“==”比较的是两个对象引用的地址是否相等,而“equals()”比较的是两个对象引用的内容是否相等,而既然要进行两个对象之间的比较,那么就必须要实现两个对象之间所有属性内容的比较。 例子:
执行结果:
垃圾收集机制 自动垃圾回收是一种在堆内存中找出哪些对象在被使用,还有哪些对象没被使用,并且将后者删掉的机制。所谓使用中的对象(已引用对象),指的是程序中有指针指向的对象;而未使用中的对象(未引用对象),则没有被任何指针给指向,因此占用的内存也可以被回收掉。 在用 C 之类的编程语言时,程序员需要自己手动分配和释放内存。而 Java 不一样,它有垃圾回收器,释放内存由回收器负责。本文接下来将介绍垃圾回收机制的基本过程。 既然我们要做垃圾回收,首先我们得搞清楚垃圾的定义是什么,哪些内存是需要回收的。 Java 中标记垃圾的算法主要有两种,引用计数法和可达性分析算法。我们首先来介绍引用计数法。 引用计数算法(Reachability Counting)是通过在对象头中分配一个空间来保存该对象被引用的次数(Reference Count)。 如果该对象被其它对象引用,则它的引用计数加 1,如果删除对该对象的引用,那么它的引用计数就减 1,当该对象的引用计数为 0 时,那么该对象就会被回收。当对象被赋值为 null 是,该对象的引用计数会变为 0 。 但是它有一个缺点:无法检测出循环引用的情况,导致内存泄露。 我们举一个简单的例子。
从上述代码中我们可以看出,object1 和 object2 并没有任何价值,但是他们循环引用,造成内存泄露。 可达性分析算法是从离散数学中引入的,也是如今正在使用的策略,程序把所有的引用关系看作一张图(DOM 图类似),从一个节点 GC ROOT 开始,寻找对应的引用节点,找到这个节点以后,继续寻找这个节点的引用节点,就如递归思想一般,遍历所有,当所有的引用节点寻找完毕之后,剩余的节点则被认为是没有被引用到的节点,即无用的节点,无用的节点将会被判定为是可回收的对象。 通过可达性算法,成功解决了引用计数所无法解决的问题-“循环依赖”,只要你无法与 GC Root 建立直接或间接的连接,系统就会判定你为可回收对象。那这样就引申出了另一个问题,哪些属于 GC Root。 在 Java 语言中,可作为 GC Root 的对象包括以下 4 种:
在确定了哪些垃圾可以被回收后,垃圾收集器要做的事情就是开始进行垃圾回收,但是这里面涉及到一个问题是:如何高效地进行垃圾回收。 标记-清除算法(Mark-Sweep)是最基础的一种垃圾回收算法,它分为 2 部分,先把内存区域中的这些对象进行标记,哪些属于可回收标记出来,然后把这些垃圾拎出来清理掉。清理掉的垃圾就变成未使用的内存区域,等待被再次使用。 这逻辑再清晰不过了,并且也很好操作,但它存在一个很大的问题,那就是内存碎片。当我们将垃圾回收完,内存会被切分成很多段。 我们知道开辟内存空间时,需要的是连续的内存区域,如果这时候我们需要一个 2M 的内存区域,其中有 2 个 1M 是没法用的。这样就导致,其实我们本身还有这么多的内存的,但却用不了。 复制算法(Copying)是在标记清除算法上演化而来,解决标记清除算法的内存碎片问题。 它将可用内存按容量划分为大小相等的两块,每次只使用其中的一块。当这一块的内存用完了,就将还存活着的对象复制到另外一块上面,然后再把已使用过的内存空间一次清理掉。 保证了内存的连续可用,内存分配时也就不用考虑内存碎片等复杂情况,逻辑清晰,运行高效。 但是它也很明显的暴露了另一个问题,假设我有一个 140 平米的房子,那么就只能当 70 平米的小两房来使,代价实在太高。 标记-整理算法(Mark-Compact)的标记过程仍然与标记清除算法一样,但后续步骤不是直接对可回收对象进行清理,而是让所有存活的对象都向一端移动,再清理掉端边界以外的内存区域。 标记-整理算法一方面在标记-清除算法上做了升级,解决了内存碎片的问题,也规避了复制算法只能利用一半内存区域的弊端。 看起来很美好,但它对内存变动更频繁,需要整理所有存活对象的引用地址,在效率上比复制算法要差很多。 分代收集算法(Generational Collection)严格来说并不是一种思想或理论,而是融合上述 3 种基础的算法思想,而产生的针对不同情况所采用不同算法的一套组合拳。 对象存活周期的不同将内存划分为几块。一般是把 Java 堆分为新生代和老年代,这样就可以根据各个年代的特点采用适当的收集算法。 在新生代中,每次垃圾收集时都发现有大批对象死去,只有少量存活,那就选用复制算法,只需要付出少量存活对象的复制成本就可以完成收集。 而老年代中因为对象存活率高、没有额外空间对它进行分配担保,就必须使用标记-清理或者标记-整理算法来进行回收。
|
|
|
上一篇文章 下一篇文章 查看所有文章 |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 | -2024/11/24 11:06:55- |
|
网站联系: qq:121756557 email:121756557@qq.com IT数码 |