自定义博客皮肤VIP专享

*博客头图:

格式为PNG、JPG,宽度*高度大于1920*100像素,不超过2MB,主视觉建议放在右侧,请参照线上博客头图

请上传大于1920*100像素的图片!

博客底图:

图片格式为PNG、JPG,不超过1MB,可上下左右平铺至整个背景

栏目图:

图片格式为PNG、JPG,图片宽度*高度为300*38像素,不超过0.5MB

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

-+
  • 博客(18)
  • 问答 (2)
  • 收藏
  • 关注

原创 代码随想录算法跟练 | Day2 | 数组Part2

我们可以发现,在暴力解法里,每次更新起始点后的累加计算里,其实出现了较多的重复计算,我们可以考虑是否有办法避免这种情况。因此有如下实现思路:维护两个指针标记当前数组还未进行计算的部分的首尾,然后计算这两个指针指向元素的平方值,将得到的较大的值。,我们可以想到,用两个指针来标记区间的首尾,然后维护一个变量来表示这个区间所有元素的总和,这就是。我们只需要不断滑动区间的首尾指针来标记合适的区间范围,就可以通过单次遍历操作来达成题目的需求。到新的数组序列中(可以对新的数组维护一个从后往前移动的指针),保证。

2024-05-23 22:39:26 424

原创 代码随想录算法跟练 | Day1 | 数组基础Part1

我们可以很轻松地想到暴力解法,即遍历数组的同时进行判断,如果出现需要移除的元素,则通过循环将该元素后的所有元素前移一位即可,同时维护一个变量记录数组长度就能满足所有需求。通过快指针去对数组进行遍历操作,慢指针来标记当前最高有效位的下一位,然后把遍历到的有效元素存入到慢指针指向的位置即可,这种算法因为避免了数组元素批量移动时的遍历操作,时间复杂度是。这部分知识点相对来说比较简单,通常情况下,暴力解法也能满足需求,但是当出现重复遍历的情况时,其实可以考虑一些常见的优化方式,如这里的双指针法。

2024-05-22 13:12:26 878

原创 《深入理解 Java 虚拟机》学习笔记 Day16(HotSpot 垃圾收集算法的实现细节:根节点枚举)

可达性分析算法从 GC Roots 集合中查找引用链的操作里,固定可作为的 GC Roots 的节点目标较为明确,但是要想做到高效的查找并非容易的事,尤其是现在 Java 程序越来越庞大,逐个检查引用肯定要消耗不少时间。中才能正常进行,在这个过程里,分析时根节点集合的对象引用关系不能变化,如果这一点不能保证,分析结果的准确性就不能保证,这也是为什么垃圾收集过程里,根节点枚举必须暂停用户线程。前面学习的垃圾收集相关算法在实现时,对于执行效率有严格的考量,因此了解实现细节也是比较重要的一点。

2024-05-11 00:05:10 269 1

原创 《深入理解 Java 虚拟机》学习笔记 Day15(常见垃圾收集算法:标记 - 清除算法、标记 - 复制算法、标记 - 整理算法)

过去有一种名为“半区复制”的垃圾收集算法,即把可用内存按容量划分为大小相等的两部分,每次只使用其中的一块内存,当这一块内存用完了,就把内存中还存活的对象复制到另一块内存上,把使用过的内存一次清理完毕,这样简单高效,但是缺点也很明显——对于老年代的特性,标记 - 整理算法被提出,其标记过程与标记 - 清除算法一样,但后续的步骤不是直接对可回收对象进行清理,而是把所有存活对象向内存空间一端移动,然后直接清除掉边界以外的内存。标记对象的过程就是前几天学习的垃圾的判定过程,主要是使用可达性分析算法进行判断。

2024-05-10 01:11:46 600

原创 《深入理解 Java 虚拟机》学习笔记 Day14(垃圾收集器与内存分配:垃圾收集算法之分代收集理论)

即如果当前进行一次局限于新生代区域的垃圾收集(Minor GC),但新生代中的对象完全有可能被老年代所引用,为了找出这个区域内的存活对象,就需要在固定的 GC Roots 之外再额外遍历整个老年代所有对象来确保可达性分析结果的正确性,反过来也是如此。在这之后,如果一个区域内大部分对象都是朝生夕灭的,难以熬过垃圾收集过程,把他们集中在一起,每次收集的时候就只需要关注如何保留少量存活对象而不是标记大量要被回收的对象,就可以。,如“标记 - 复制算法”“标记 - 清除算法”“标记 - 整理算法”等。

2024-05-09 00:05:03 469

原创 《深入理解 Java 虚拟机》学习笔记 Day13(垃圾收集器与内存分配:回收方法区)

Java 堆中尤其是新生代中往往一次垃圾收集就能够回收 70% 至 99% 的内存空间,而方法区因为其苛刻的判定条件,回收成果往往远低于此。加载该类的类加载器已经被回收,这个条件除非是经过精心设计的可替换类加载器的场景,如OSGi、JSP的重加载等,否则通常是很难达成的。常量池中的一个常量,且虚拟机中没有其他地方引用这个字面量,而如果此时发生内存回收,而且。该类所有的实例都已经被回收,也就是Java堆中不存在该类及其任何派生子类的实例。其中,废弃常量的回收类似于 Java 堆中对象的回收,如果系统中。

2024-05-08 00:05:57 135

原创 《深入理解 Java 虚拟机》学习笔记 Day12(垃圾收集器与内存分配:对象的生存与死亡 - 过时的 finalize方法)

但是作者提到,不建议使用甚至是建议避免使用它,因为当前官方已经明确声明为不推荐的语法,它运行代价高昂,不确定性大,无法保证更改对象的调用顺序。要真正宣告一个对象死亡,最多会经历两次标记过程:如果对象在进行可达性分析后发现没有与 GC Roots 相连接的引用链,它将会被第一次标记,方法是对象拯救自己的最后一次机会,如果在方法中,对象重新与引用链上的任何一个对象建立关联,那么在第二次标记时它将会被移出“即将回收”的集合。或者其他方式都能做的更好更及时,这是在某些落后的教材中才会被推荐使用的方法。

2024-05-06 23:18:05 169 2

原创 《深入理解 Java 虚拟机》学习笔记 Day11(垃圾收集器与内存分配:可达性分析算法、Java 中引用的概念)

这个定义并没有问题,但在现在看来过于狭隘了,一个对象只有“被引用”和“未被引用”的两种状态,无法描述一些“食之无味弃之可惜”的对象。也被称为“幽灵引用”或者“幻影引用”,它是最弱的一种引用关系,一个对象是否有虚引用存在,完全不会对齐生存时间构成影响,也无法通过虚引用来取得一个对象实例。只被软引用关联的对象,在系统将要发生内存溢出异常前,会把这些对象列入到回收范围内进行第二次回收,如果这次回收后还没有足够的内存,才会抛出内存溢出异常。强引用就是最传统引用的定义,指的是在程序代码中普遍存在的引用赋值,如。

2024-05-05 23:48:45 632 1

原创 《深入理解 Java 虚拟机》学习笔记 Day10(垃圾收集器与内存分配策略概述、引用计数算法)

哪些内存需要回收?什么时候回收?如何回收?在第 2 章的学习中,我们知道,程序计数器、虚拟机栈、本地方法栈这 3 个区域随线程而生,随线程而灭,这几个区域的内存分配和回收都具备确定性,不需要过多考虑如何进行回收的问题,因为当方法结束或者线程结束时,内存自然就跟随着回收了。而 Java 堆和方法区则有显著的不确定性,只有在运行期间我们才能知道程序究竟会创建哪些对象,创建多少对象,这部分的内存分配和回收是动态的。垃圾收集器关注的正是这部分内存该如何管理。

2024-05-05 00:47:42 370 1

原创 《深入理解 Java 虚拟机》学习笔记 Day9(OutOfMemoryError 异常:本机直接内存溢出)

作者最后进行了延伸:要排查直接内存导致的内存溢出,首先可以看 Heap Dump 文件中是否有明显异常情况,直接内存导致的内存溢出的一个。方法指定只有引导类加载器才会返回实例,体现设计中希望只要虚拟机标准类库里面的类才能使用。如果内存溢出后产生的 Dump 文件很小,程序中又间接使用了。),就可以重点考虑这方面的原因。尝试直接通过反射获取。方法来申请分配内存(

2024-05-03 21:46:34 494 1

原创 《深入理解 Java 虚拟机》学习笔记 Day8(OutOfMemoryError 异常:方法区和运行时常量池溢出)

指定元空间的初始空间大小,以字节为单位,达到该值就会触发垃圾收集进行类型卸载,同时收集器会对该值进行调整:如果释放了大量的空间,就适当降低该值;而在 JDK 8 之后,永久代完全退出历史舞台,元空间代替其存在,前面的这些方法已经很难破事虚拟机产生方法区的溢出异常了。一个类要被垃圾收集器回收,条件是比较苛刻的,因此在运行时生成大量动态类的应用场景里,就应该特别关注这些类的回收状况。:作用是在垃圾收集之后控制最小的元空间剩余容量的百分比,可减少因为元空间不足导致的垃圾收集的频率。

2024-05-02 23:30:45 344 3

原创 《深入理解 Java 虚拟机》学习笔记 Day7(OutOfMemoryError 异常实战:Java 堆溢出)

验证第二种情况,使用如下代码,定义大量变量来多占局部变量表空间/*** Java 虚拟机栈 StackOverflowError实验二:定义大量的本地变量,增大当前方法帧中本地变量表的长度*/try {throw e;结果如下,依然是抛出。

2024-05-01 22:24:24 569 3

原创 《深入理解 Java 虚拟机》学习笔记 Day6(OutOfMemoryError 异常实战:Java 堆溢出)

如果是内存泄漏,可进一步通过工具查看泄漏对象到GC Roots的引用链,找到泄漏对象是通过怎样的引用路径、与哪些GC Roots相关联,才导致垃圾收集器无法回收它们,根据泄漏对象的类型信息以及它到GC Roots引用链的信息,一般可以比较准确地定位到这些对象创建的位置,进而找出产生内存泄漏的代码的具体位置。如果不是内存泄漏,换句话说就是内存中的对象确实都是必须存活的,那就应当检查Java虚拟机的堆参数(-Xmx与-Xms)设置,与机器的内存对比,看看是否还有向上调整的空间。展开可以发现,就是海量的。

2024-04-30 23:54:02 117 1

原创 《深入理解 Java 虚拟机》学习笔记 Day5(HotSpot 虚拟机对象:对象的访问定位)

使用直接指针访问的最大好处就是速度更快,节省了一次指针定位的时间开销,由于对象访问在 Java 中非常频繁,所以这类开销积少成多也是一项比较大的执行成本。reference 中存储的是稳定的句柄地址,在对象被移动(如在垃圾收集时进行移动)时,只会改变句柄中的实例数据地址,而 reference 本身不需要被修改。前几天学到的,Java 虚拟机栈上的局部变量表中存储了 reference 类型的对象引用。中会划分出一块内存作为句柄池,reference 中存储的就是对象的。

2024-04-29 23:14:17 218 2

原创 《深入理解 Java 虚拟机》学习笔记 Day4(HotSpot 虚拟机对象:对象的内存布局)

对象如果是一个 Java 数组,对象头中还必须有一块用于记录数组长度的数据,因为虚拟机可以通过普通 Java 对象的元数据信息确定 Java 对象的大学,但是如果数组长度不确定,将无法确定数组大小。这并不是必然存在的,也没有特别的含义,它仅仅起着占位符的作用。,从以上默认的分配策略中可以看到,相同宽度的字段总是被分配到一起存放,在满足这个前提条件的情况下,在父类中定义的变量会出现在子类之前。,就是我们在代码里面定义的各种类型的字段内容,无论是从父类继承下来的,还是在子类中定义的字段都必须记录起来。

2024-04-28 22:51:12 402

原创 《深入理解 Java 虚拟机》学习笔记 Day3(HotSpot 虚拟机对象:对象的创建)

在前文完成对虚拟机运行时数据区域完成初步介绍后,部分以 HotSpot 虚拟机和最常用的内存区域 Java 堆为例,深入探讨了 HotSpot 虚拟机在 Java 堆中对象分配、布局和访问的全过程。

2024-04-27 23:45:18 783 1

原创 《深入理解 Java 虚拟机》学习笔记 Day2(运行时数据区域:Java 堆、方法区、运行时常量池,直接内存)

如何实现方法区原则上属于虚拟机实现细节,过去 HotSpot 虚拟机选择把收集器的分代设计扩展至方法区,使用永久代(Permanent Generation)实现方法区,使得 HotSpot 的垃圾收集器可以像管理 Java 堆一样管理这部分内存,但导致了容易出现内存溢出的问题,曾出现若干严重 Bug 就是由于低版本的 HotSpot 虚拟机对此区域没有完全回收导致内存泄漏。,并非某个 Java 虚拟机具体实现的固有内存布局,更不是 Java 虚拟机规范中对 Java 虚拟机的进一步划分。

2024-04-26 23:15:42 728 4

原创 《深入理解 Java 虚拟机》学习笔记 Day1(运行时数据区域:程序计数器、Java 虚拟机栈、本地方法栈)

相比C、C++等语言,开发 Java 程序时在虚拟机自动内存管理机制的帮助下,不需要手动对对象生命周期进行维护。但如果出现内存泄漏或者内存溢出方面的问题,很难排查错误、修正问题。-> 学习内容:了解虚拟机如何控制内存-> 学习目的:掌握排查、修正内存泄漏和溢出方面的问题的能力。

2024-04-25 02:29:43 353 4

空空如也

TA创建的收藏夹 TA关注的收藏夹

TA关注的人

提示
确定要删除当前文章?
取消 删除