jdk7默认gc算法

在定期检查JDK中是否存在一种或另一种标准算法时,我决定进行这种索引。 有趣的是,为什么其中包含一些著名的数据结构或算法,而其他却没有? 此调查的格式仅涉及JDK的算法和数据结构的关键特性和功能,所有详细信息和完整描述-您可以在javadoc或jdk源代码中轻松找到。 让我们从简单开始到复杂!

JDK的数据结构

叠放

jdk中有一个堆栈 ,它是从堆栈中出现的-类Stack ,但不建议使用它,它很复杂又很奇怪:它继承自Vector ,因此基于Dynamic Array并已同步。 为什么一个简单的栈需要这一切,为什么它不只是一个接口-目前尚不清楚(讨论过很多次: 1 , 2 ),但似乎只是一个架构的错误,同样与载体本身。 顺便说一句,JDK作者自己建议使用Deque代替。

Deque – 双端队列的接口(api)(O中的LIFO + FIFO(1)),其中包括堆栈操作(push,pop,isEmpty,size),并且到目前为止在jdk中可用(1.6+) 。 当然,将这些堆栈操作放在接口Stack中是更合乎逻辑的,例如让Deque继承它,但是由于Stack已经存在,并且向后兼容性是Java的“圣杯” –他们必须牺牲常规设计。 Deque的实现是ArrayDeque和LinkedList ,它们也是常规队列的实现者–因此我们将在后面讨论。

队列

接下来,让我们看一下队列数据类型 。 这里的一切都很好,设计得很好。 队列 – FIFO队列的接口(api),以恒定时间O(1)添加到开头并从结尾删除。

主要实现有: ArrayDeque ,基于动态可扩展数组的循环缓冲区 (填充时加倍)和LinkedList ( 经典的双向链接列表) (大小不受限制)。 令人惊讶的是,第一个不支持随机访问 (使用索引添加/删除/获取),第二个却支持O(n)时间,并通过链表进行迭代。 这些类还实现了上面提到的Deque,因此它们支持从末尾移除并在固定时间内添加到顶部。

接下来,从jdk 1.5+开始,添加了PriorityQueue ,这实际上违反了约定,因为队列元素不是从结尾检索的(并且也不添加到头部),而是根据它们的优先级检索的。 PriorityQueue基于可扩展的二进制堆 ,其顶部最小(根据其比较器),并且在填充时提高了1.5倍。 关键特征分别是:元素的添加/删除在O(log N)中,而对最小值(head)的引用在O(1)中。

其他类型的队列专为多线程使用而设计,它们是: BlockingQueue , TransferQueue , ConcurrentLinkedQueue和ConcurrentLinkedDeque 。

BlockingQueue ( ArrayBlockingQueue , LinkedBlockingQueue , PriorityBlockingQueue )的实现是其原始版本的一种同步版本,即几乎每个操作都是串行执行的(具有独占锁定)。 对于DelayQueue也是如此:也是同步的,并且在内部使用PriorityQueue 。

其他实现: SynchronousQueue , TransferQueue ( LinkedTransferQueue ), ConcurrentLinkedQueue , ConcurrentLinkedDeque –基于不同的方法:它们使用基于链表和CAS指令的非阻塞队列算法,这些算法在多处理器环境中可以很好地并行化。 详细描述在源代码中。

此类算法的理论是一个非常庞大且现代的主题,因此尚未很好地标准化和结构化,它们不在本文的讨论范围之内。

优先队列

就像从jdk 1.5+开始所说的那样,有一个通用的PriorityQueue根据元素比较器工作。 而且,jdk中还有堆的另一种实现。 这是很好的旧Timer ,它是内部类– TaskQueue(顶部的延迟最小的任务)。 当然,这是一个私有类,除了在Timer内部,不能使用。

清单

如您所知,有顺序和/或随机访问类型列表。 在Java中,它是List ,主要有2种实现:首先-是ArrayList ,支持随机访问 ,基于动态可扩展数组 (填充时增加一半),但是在删除所有元素后不会缩小,您需要调用a特殊方法( trimToSize )。

第二个-再次是LinkedList,它是一个双链表顺序访问大小,仅受jvm的内存限制。 尽管也存在随机访问(索引)的方法–如前所述,它们需要O(n)时间。

因此,java集合中没有最简单的链表实现,尽管这是一个好主意(链接的开销减少了2倍),并且没有简单的堆栈。

要在多线程环境中使用列表,有几个选项: CopyOnWriteArrayList (更改操作– O(n)),包装器( synchonizedList )以及过时的Vector 。

符号表

它们在JDK中显示为二进制树和哈希表。 二叉树 –它是TreeMap (或TreeSet ), SortedMap (也是SortedSet)的实现,它基于经典的红黑树 ,即是平衡的,并且对于O(log N)保证了其基本操作,并且不限大小。 jdk中不存在其他类型的树。

哈希表是HashMap (也是HashSet ),它可能是Java中最常用的结构,它基于可动态扩展的哈希表,该哈希表与链表分别链接 ,具有所有功能:性能取决于哈希函数的质量,因此最坏的情况是O(N)。 当大小达到预定的loadFactor时, HashMap的大小将增加一倍。 值得注意的是,为了保护坏的哈希函数,使用了双哈希,并且对hashCode()的调用结果采用了棘手的位算法。

JDK中也有带有开放地址(线性探测)的哈希表实现。 其中之一是IdentityHashMap ,当键和值都存储在彼此相邻的同一数组中时,它会使用经典线性探测的优化版本,以实现更好的数据缓存(javadoc:«大型表的局部性比使用单独的数组»)

第二种开放寻址实现是非常特定的:它仅用于存储ThreadLocal元素( ThreadLocalMap中的内部隐藏类),当然不可用。

还有多线程版本: ConcurrentHashMap中 ,包装synchronizedMap , 哈希表和ConcurrentSkipListMap 。 包装器-自然只是阻止了常规HashMap Hashtable的版本-同一件事(它是旧有的,不建议使用), ConcurrentHashMap-锁条版本,减少了关键的锁部分(最好阅读JCiP ,这里是( 摘录 ) ConcurrentSkipListMap –是哈希表的非阻塞命名算法的改编版(有关详细信息,请参见源代码)。

集合(不包含重复项)-它是用Java 设置的,并且通过HashMap实现,因此所有被称为哈希表的对象-对HashSet有效。

图表

图结构和算法未在jdk中表示。 因此,您只能为此使用第三方库。

弦乐

java中通常有一个字符串实现:基于unicode字符数组。 值得一提的是,从1.7_17版本开始–子字符串的性能为O(n),因为已复制了子字符串。

有趣的是, 此实现使用了一种简单的(强力)子字符串搜索算法,该算法在最坏的情况下以O(N * M)运行,并且没有一些有效的算法(在有限状态机上构建:Knuth-Morris-Pratt等) 。

原因有以下几种:字母UTF字符大(〜65K),因此存储状态机的开销很大,而暴力破解算法就位(不使用额外的内存)。 其次,在平均输入字符串上–该算法在统计上与其他算法相比并没有很多。

与排序相同:存在有效的基数排序字符串algs(LSD,MSD等),但在jdk中,有一个用于字符串的标准对象排序 ,如果运行,则以O(M * N * log N)运行大部分线相差不大(M –线长)。 原因是相同的:快速计数字符串算法需要额外的UTF字母大小的数组,这使得它们在平均输入上非常无效。

JDK算法

排序

由于jdk7发生了许多有关各种选项的更改,因此讨论了很多次,关于此主题的信息和文章很多,您可以轻松地搜索它。

简而言之,这是jdk中排序实现的实际列表: TimSort –默认情况下对对象进行排序; mergesort –还用于对象;旧版本(通过系统属性启用); Dual-Pivot Quick sort –用于基元;然后按计数排序用于字节/字符数组,最后插入排序用于任何情况下使用的小数组。

集合内容使用Collections.sort(List…)进行排序,仍然可以通过将集合复制到数组中,对其进行排序,然后相应地覆盖集合内容来完成。 因此,尽管没有开销,对集合进行排序仍然是不可能的,尽管我认为拥有就地排序的链表是一个好主意。 Java中的字符串排序也使用对象版本完成,原因已经提到。

正在搜寻

对于原语和对象的所有数组以及随机访问列表实现(例如ArrayList等),都存在传统的二进制搜索 。 此外,JDK中还有一个二进制搜索链接列表的版本! 令人惊讶的是:JDK没有对链表进行排序,但是对它们进行二进制搜索! 尽管没有太大意义,因为这种版本的性能为O(N)。

常用表达

为此提供了Pattern和Matcher类。 Java使用基于带回溯的非确定性有限状态机( NFA )的传统实现。 因此,在退化的输入上,在最坏的情况下它给出了指数复杂度 O(m ^ N),例如,在Java中运行此regexp并尝试添加/删除“ a”符号:“ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.aa )* b”)

另外,还有所谓的有序交替-此功能可在找到第一个匹配项后停止搜索,但不会显示最具体(最长)的搜索结果( 例如 )。

哈希函数,校验和

jdk中有hashCode实现的六个版本,并且Park-Miller_random_number_generator是默认版本,其他很简单,例如常量或对象内存地址,并且不使用算法,可以在c ++ jdk源代码中找到它们。 MessageDigest类中还有行业标准的哈希算法(SHA-*,MD5和变体)。

对于校验和,有Adler-32 ( javadoc )和CRC32 ( javadoc )算法的实现。

压缩

jdk中有一个标准的压缩deflate( Deflater )算法的实现,并且zip / gzip jdk utils使用它。 它们都在java.util.zip包中 。

摘要

如您所见,经典数据结构并未完全用Java呈现,但与此同时,几乎所有jdk中的所有数据结构都可以使用很多线程安全版本。 缺少的是一个悬而未决的问题。 例如,您可以争论jdk是否需要一些Union-Find,但是在社交网络时代完全缺少该语言的图形结构和算法会非常令人惊讶,并且实际上会产生很多错误和问题。

参考:来自我们的JCG合作伙伴 Mikhail Baturov 的JDK 7的算法和数据结构,这是另一个俄罗斯编程人员.blog博客。

翻译自: https://www.javacodegeeks.com/2013/07/algorithms-and-data-structures-of-jdk-7.html

jdk7默认gc算法

jdk7默认gc算法_JDK 7的算法和数据结构相关推荐

  1. JDK默认GC算法是个谜

    JDK默认GC算法是个谜 背景 我们系统采用openjdk:8u212-b04-jdk-stretch作为基础镜像,java -version命令输出: openjdk version "1 ...

  2. JVM内存管理------GC算法精解(五分钟教你终极算法---分代搜集算法)

    转载自   JVM内存管理------GC算法精解(五分钟教你终极算法---分代搜集算法) 引言 何为终极算法? 其实就是现在的JVM采用的算法,并非真正的终极.说不定若干年以后,还会有新的终极算法, ...

  3. JVM(3)之垃圾回收(GC垃圾收集器+垃圾回收算法+安全点+记忆集与卡表+并发可达性分析......)

    <深入理解java虚拟机>+宋红康老师+阳哥大厂面试题2总结整理 一.堆的结构组成 堆位于运行时数据区中是线程共享的.一个进程对应一个jvm实例.一个jvm实例对应一个运行时数据区.一个运 ...

  4. JVM内存管理------GC算法精解(复制算法与标记/整理算法)

    转载自  JVM内存管理------GC算法精解(复制算法与标记/整理算法) 本次LZ和各位分享GC最后两种算法,复制算法以及标记/整理算法.上一章在讲解标记/清除算法时已经提到过,这两种算法都是在此 ...

  5. 深入理解java虚拟机(三)GC垃圾回收-对象存活算法

    文章目录 前言 一.引用计数算法 二.可达性分析算法 三.了解引用 结尾 前言 在堆里面存放着Java世界中几乎所有的对象实例,垃圾收集器在对堆进行回收前,第一件事情就是要确定这些对象之中哪些还&qu ...

  6. 垃圾回收算法_垃圾回收算法有哪些

    垃圾检测通常通过建立一个根对象的集合以及建立一个从这些根对象开始能够触及的对象集合来实现.如果正在执行的程序可以访问到根对象和某个对象之间存在引用路径,这个对象就是可触及的.对于程序来说,根对象总是可 ...

  7. 内存回收算法与 Hot Spot 算法实现细节

    文章目录 内存回收算法概述 对象存活判定算法 引用计数算法 可达性分析算法 垃圾收集算法 分代收集理论 标记-清除算法 标记-复制算法 半区复制算法 Appel 式复制算法 Appel 式复制算法的逃 ...

  8. 垃圾回收算法_Java 垃圾回收算法与几种垃圾回收器

    一.如何确定某个对象是"垃圾"? 目前主流垃圾回收器都采用的是可达性分析算法来判断对象是否已经存活,不使用引用计数算法判断对象时候存活的原因在于该算法很难解决相互引用的问题.如何确 ...

  9. 机器学习 第三讲 机器学习基础、机器学习算法(K-近邻算法、朴素贝叶斯算法)

    文章目录 一.机器学习基础 1.明确几点问题 2.机器学习算法的判别依据 3.机器学习算法分类 4.机器学习开发流程 二.机器学习算法 1.sklearn数据集 (1)数据集划分 (2)sklearn ...

最新文章

  1. lintcode: 爬楼梯
  2. 关系查询处理 查询优化 论文_每日论文33:关系数据库中的关键词查询结果动态优化...
  3. kickstart文件配置与使用
  4. 五个举措:现代化Jenkins 和终结“Jenkinsteins”
  5. Adobe产品安装错误问题:Exit Code: 7
  6. CodeForces Goodbye 2017
  7. SAP Spartacus里如何查看HTTP请求的状态
  8. 第一次接触万物接对象
  9. Freeswitch之ASR(语音识别)总结大全
  10. win10运行YOLOv4+OPENCV+VS2017
  11. POJ1917 UVA10361 Automatic Poetry【文本】
  12. POJ 2182 Lost Cows
  13. [Android6.0] StageFright解码流程小结
  14. 开源中国软件频道_编程小黑马
  15. 数学分析 函数的连续性(第4章)
  16. 腾讯这次组织变革是过渡的
  17. UE4 打包问题总结
  18. 华为未来是铺满鲜花还是荆棘遍布?
  19. 华为模拟器配置S5700交换机OSPF案例
  20. Leetcode 刷题记录

热门文章

  1. JavaFX图表(四)之面积图
  2. mybatis更新Blob类型字段要用updateByPrimaryKeyWithBLOBs
  3. jdbc事务和事务的隔离级别
  4. Spring 自动装配 ‘byType’
  5. 《走遍中国》珍藏版(四)
  6. ssh(Spring+Spring mvc+hibernate)——DeptServiceImpl.java
  7. hibernate注解实体类(Dept.java)
  8. Android 隐藏底部三个虚拟按键
  9. [Err] 1055 - Expression #1 of ORDER BY clause is not in GROUP BY clause and contains nonaggregated c
  10. jsp连接mysql数据库 例子_JSP 连接 MySQL 数据库的例子