jdk7默认gc算法_JDK 7的算法和数据结构

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算法

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/348640.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

深入浅出逻辑组合电路(2)

深入浅出逻辑组合电路(2) 门电路中的冒险现象 通常讨论逻辑电路时,只从抽象的逻辑角度进行描述,不考虑实际电路中必然存在的信 号传输时延和信号电平变化时刻对逻辑功能的影响。逻辑门的传输时延以及多个输入信号变 化时刻不同步…

学习数字电路必须知道的几种编码

2-10进制编码(BCD编码) BCD码:使用一个四位二进制代码表示一位十进制数字的编码方法。 一、8421码 选取0000~1001表示十位二进制数 0到9 按自然顺序的二进制数表示所对应的十进制数字,是有权码,从高位到地位的权依…

Packt发行的$ 5 Java编程书籍:精通Java 9,Java 9 High Performance

您好极客! 今天,我们为您带来一些激动人心的消息! Java Code Geeks和Packt联手为您提供广泛的书籍库每周折扣。 本周,我们提供Java相关书籍的折扣,以帮助您理解和掌握Java。 他们全都打折到每本书5美元 !…

深入浅出组合逻辑电路(3)常见的几种编码器

编码器是啥? 下面介绍几种常见的编码器 答:编码器是实现编码的数字电路,对于每个有效的输入信号,编码器输出与之对应的一组二进制代码。 2^n-n线编码器 是最基本的编码器 图示为8-3线译码器 输入为8个代编码信号,…

jpa命名 多条件查询命名_JPA 2 | 动态查询与命名查询

jpa命名 多条件查询命名JPA有自己的查询语言,称为JPQL。 JPQL与SQL非常相似,主要区别在于JPQL与应用程序中定义的实体一起使用,而SQL与数据库中定义的表和列名称一起使用。 在定义将对定义的Entity类执行CRUD操作的JPA查询时,JPA为…

深入浅出逻辑电路(4)介绍几种常见的译码器

译码器是啥? 输入一组二进制编码,输出一个有效的信号 译码器输入的 n 位二进制代码有2n种取值,称为2n种不同的编码值。若将每种编码分别译出,则译码器有2n个译码输出端,这种译码器称为全译码器。 若译码器的输入编码…

没有科学计数法的Java十进制数的简单字符串表示形式

Java中用于十进制数字的主要类型 /对象是float / Float , double / Double和BigDecimal 。 在每种情况下,其“默认”字符串表示形式都是“计算机科学计数法”。 这篇文章演示了一些简单的方法,可以在没有科学符号的情况下提供十进制数的字符串…

几道题帮你搞定数据选择器

这里不写答案,只讲思路 这个逻辑表达式比较短,咱们首先就考虑到先将F写成最小项表达式 从三个自变量中选择两个作为选择器的地址变量,本题为A1A0AB 然后把C处理一下,化简式子,使得式子的每一项都有AB,每一…

Spring Data Solr教程:查询方法

我们已经了解了如何配置Spring Data Solr。 我们还学习了如何向Solr索引添加新文档,如何更新现有文档的信息以及从Solr索引删除文档。 现在是时候继续前进,学习如何使用Spring Data Solr从Solr索引中搜索信息。 我们的搜索功能的要求如下: 搜…

深入浅出时序逻辑电路(1)

我们一提到时序逻辑电路,就会想到触发器 先讲讲时序逻辑电路:时序逻辑电路(常简称为时序电路)内部包含存储器,用于记忆电路的工作状态和输入变化情况,其输出由当前的输入和存储信息共同确定的一种电路。 再…

云幸福–如何在几分钟内安装新的OpenShift Container Platform 3.7

此安装需要安装Red Hat Middleware产品流(预先配置的容器选项)以及所有其他功能,例如源容器,映像容器和.Net Core容器。自OpenShift容器平台发布以来,我一直希望提供一个简单的方法。 ,完全配置且易于使用的…

从分析一个简单的时序电路入手

这道题怎么搞呢 先看图 看到了一个JK触发器,左边那个是J触发器转化为D触发器 右边那个就是JK触发器 写出两个次态方程:还有一个输出表达式:将激励函数带入表达式,求出两个次态方程 然后画出状态表: 再画出状态图&a…

组合逻辑电路运算法则

逻辑电路计算性质 与非门:有0出1,全1才0 & 或非门:有1出0,全0才1 >1 异或门:相同出0,不同出1 ⊕ 常用公式 ABAB‾\overline{B}BA AABA AAB‾\overline{B}BAB A00 A1A A*A‾\overline{A}A0 …

jmeter实现翻页功能_JMeter定制功能实现

jmeter实现翻页功能JMeter提供了可在采样器中使用的功能。 在编写复杂的测试计划时,您会觉得JMeter缺少某些方法。 您使用Beanshell脚本定义自己的自定义方法。 JMeter调用Beanshell解释器来运行脚本。 只要您不产生高负载(大量线程)&#xf…

常见的集成逻辑门(CMOS\TTL\ECL)

CMOS系列 TTL系列 ECL系列 集成逻辑门的主要性能指标 关于噪声容限UN 输出负载能力 总结一下:不管那么多,先把两个算出来,取最小的就完事了 答案:ECL,CMOS,ECL,CMOS

git如何快速提交代码(大学生适用)

众所周知,git是一个强大的版本控制工具 git的学习成本比较高,但大学生常用的功能也就那么几个 首先你需要下载一个git,生成一个密钥 生成方法:打开git(bash) $ ssh-keygen -t rsa -C “你的邮箱地址”&a…

Spring框架–应用程序上下文–到达应用程序上下文的三种方法

本文向您展示了三种不同的方式来获取代码中的Spring Framework Application Context。 摘要 (这是我在2010年撰写的旧文章的转贴)。 在Google中搜索“ Spring ApplicationContextAware ”时,您会遇到很多建议,而且我也看到很多人…

最简单的语言来说JAVA中的NEW到底怎么搞

new 到底是干啥的? JAVA中的new关键字就是在你声明了一个对象后,来给对象分配相应的内存,可以使用任何public来构造 People stunew People( ); new 在堆中为对象申请了一块空间,new也使用了父类的构造方法 java里的new的英文意…

34个计算机网络易错知识点总结

不属于网络体系结构所描述的内容是:协议的内部实现细节OSI模型中第N层为第N1层提供服务自下而上第一个提供端到端服务的是传输层通信子网:1.高速链路2.交换机3.路由器TCP/IP模型中一共由四层,分别是: 1.应用层:应用层是…

mongodb副本集_设置MongoDB副本集分为4个步骤

mongodb副本集介绍 在详细介绍配置MongoDB副本集之前,让我简要介绍一下它们: 副本集是Mongodb数据库提供的功能,可实现高可用性和自动故障转移。 它是一种传统的主从配置,但具有自动故障转移功能。 基本上,它是mong…