Java8 Hash改进/内存改进
又开新坑o(*≧▽≦)ツ讲讲几个Java版本的特性,先开始Java8,
HashMap的改进
HashMap采用哈希算法,先使用hashCode()判断哈希值是否相同,如果相同,再使用equals(),如果再相同,则会替换掉原先的值,如不同则形成链表,后来的放前,原先的被挤到后面去,这种情况叫碰撞,我们应该要尽量避免这种情况,所以我们要通过改进hashCode()和equals(),当然我们无法完全避免这种情况。
为了不让链表太长,HashMap提供了加载因子,0.75,当元素到达哈希表的75%时,进行扩容,如果设定到100%扩容,也许算出的哈希值就只有那几个,比如长度为16的哈希表,一直只存3,5,7,8,其他的哈希值所在的位置无人问津,这样就会产生很长的链影响性能。那么哈希值可以取很小吗?也不可以,这样会频繁扩容,浪费空间。
一旦扩容,会将链表里的元素,每个重新计算新的位置,这样碰撞概率就会变低。
即使有这种扩容机制,但是碰撞依旧避免不了,所以意味着效率变低,打个比方,在1.8之前Java采用数组+链表方式,如果产生了冲突情况,比如我找哈希值为3的值,就要从数组索引值为3的链表头开始找,最糟糕的情况是找到这个链表的尾部,因此1.8将这种结构改进,变成数组+链表+红黑树 。
当链表上碰撞的个数大于8,总容量大于64,就会将链表转换成红黑树,这样的好处,除了添加,其他操作都要比链表快。
ConcurrentHashMap
1.7之前,并发级别默认为16,concurrentLevel=16;现在来介绍一下ConcurrentHashMap:
ConcurrentHashMap的数据结构是由一个Segment数组和多个HashEntry组成,主要实现原理是实现了锁分离的思路解决了多线程的安全问题,如下图所示:
Segment数组的意义就是将一个大的table分割成多个小的table来进行加锁,也就是上面的提到的锁分离技术,而每一个Segment元素存储的是HashEntry数组+链表,这个和HashMap的数据存储结构一样。
ConcurrentHashMap 与HashMap和Hashtable 最大的不同在于:put和 get 两次Hash到达指定的HashEntry,第一次hash到达Segment,第二次到达Segment里面的Entry,然后在遍历entry链表。
JDK1.8的实现已经摒弃了Segment的概念,而是直接用Node数组+链表+红黑树的数据结构来实现,并发控制使用Synchronized和CAS来操作,整个看起来就像是优化过且线程安全的HashMap,虽然在JDK1.8中还能看到Segment的数据结构,但是已经简化了属性,只是为了兼容旧版本。
内存改进
内存分为三大块,栈、堆、方法区,之前方法区其实属于堆的永久区的一部分,可是我们平常都把它分开画,因为JDK1.8取消这块方法区,取而代之的是MetaSpace(元空间),最大特色是它直接使用物理内存,而不是使用分配内存,这说明垃圾回收机制运行机制概率变低,效率提升。也就是说OutOfMemoryError,几乎不会发生。
既然如此,一些调优条件就无效了,比如PremGenSize、MaxPremGenSize,取而代之的是MetaspaceSize MaxMetaspaceSize
参考博文:
https://www.cnblogs.com/duanxz/p/3520829.html
https://www.jianshu.com/p/a7767e6ff2a2
Java8 Hash改进/内存改进的更多相关文章
- 为什么hash作为内存使用的经典数据结构?
听到这样说法:hash是内存中使用的经典数据结构.内存是典型的随机访问设备. 为什么hash这种数据结构很适合内存使用呢?如何理解内存是随机访问设备呢? 因为我想知其所以然,如何理解背后的原因,我花费 ...
- Java8 读写锁的改进:StampedLock(笔记)
StampedLock是Java8引入的一种新的所机制,简单的理解,可以认为它是读写锁的一个改进版本,读写锁虽然分离了读和写的功能,使得读与读之间可以完全并发,但是读和写之间依然是冲突的,读 ...
- java8新特性:内存和lambda表达式
1.内存变化 取消了永久区和方法区,取而代之的是MetaSpace元空间,即直接使用物理内存,即电脑内存8G则直接使用8g内存,而不是分配内存.因为内存改变,所以调整性能对应的调整参数也随之改变. 2 ...
- 美团分布式ID生成框架Leaf源码分析及优化改进
本文主要是对美团的分布式ID框架Leaf的原理进行介绍,针对Leaf原项目中的一些issue,对Leaf项目进行功能增强,问题修复及优化改进,改进后的项目地址在这里: Leaf项目改进计划 https ...
- 【译】ASP.NET Core 6 中的性能改进
原文 | Brennan Conroy 翻译 | 郑子铭 受到 Stephen Toub 关于 .NET 性能的博文的启发,我们正在写一篇类似的文章来强调 6.0 中对 ASP.NET Core 所做 ...
- Fedora 24最新工作站版本之四大重要改进
导读 2014年,Fedora.next倡议正式开始建立Fedora Linux未来十年的发展规划.从本质上讲,这项规划旨在进一步使Fedora不再只是一套汇聚多种开源产品的通用库(例如Debian) ...
- 改进的newlisp编译脚本,只需要配置
前面有一篇Say bye to CMake and Makefile我开始用自己编写的newlisp脚本替代CMake,今天对前面的进行改进. 改进部分是: 1. newlisp armory模块的引 ...
- 团队作业3-需求改进&原型设计
选题:实验室报修系统 实验室设备经常会发生这样或那样的故障,靠值班人员登记设备故障现象,维护人员查看故障记录,进行维修,然后登记维修过程与内容,以备日后复查,用这种方式进行设备运营管理,它仅仅起到一个 ...
- k-means算法的优缺点以及改进
大家接触的第一个聚类方法,十有八九都是K-means聚类啦.该算法十分容易理解,也很容易实现.其实几乎所有的机器学习和数据挖掘算法都有其优点和缺点.那么K-means的缺点是什么呢? 总结为下: (1 ...
随机推荐
- C# SHA256加密算法记录
using System.Text; using System.Diagnostics; using System.Security; using System.Security.Cryptograp ...
- 解决Zabbix网页端Get value error: cannot connect to [[192.168.238.139]:10050]: [113] No route to host问题
在安装配置完zabbix_agentd以后,网页端出现 Get value error: cannot connect to [[192.168.238.139]:10050]: [113] No ...
- wpf小技巧——datagrid 滚动条问题
今天在项目中遇到了一个问题,datagrid 不出现滚动条了,拿出来给大家分享下,以作前车之鉴. 很简单的布局代码如下 <Window x:Class="DataGrid_AutoSi ...
- iptables nat 技术转发
NAT 一. 什么是 NAT NAT(Network Address Translation)译为网络地址转换.通常路由器在转发我们的数据包时,仅仅会将源MAC地址换成自己的MAC地址,但是NAT技术 ...
- 【转】ajax发送请求时候为什么会报拒绝设置不安全的header
浏览器不允许用户手动设置敏感的Http header包括但不限于cookie.host.referer 为了安全,跨域XHR对象有一些限制: 不能使用 setRequestHeader() 设置自定义 ...
- 仿照wtform自定义Form组件
仿照wtforms自定义Form组件 1.wtforms 点击查看源码分析及使用方法 2.自定义Form组件 #!usr/bin/env python # -*- coding:utf-8 -*- f ...
- flink1.7自定义source实现
flink读取source data 数据的来源是flink程序从中读取输入的地方.我们可以使用StreamExecutionEnvironment.addSource(sourceFunction) ...
- 小P的字符串
题目描述 小P最近在研究字符编码,给出一串由0.1组成的字符串,从中任意进行截取,如果截取的字符串对应一个英文字母的ASCII值,小P就把这个0.1串叫字母子串,问给定的字符串最多能截取出多少个字母子 ...
- 2198: 小P当志愿者送餐
题目描述 在ICPC程序设计大赛期间,小P作为志愿者的任务是给各个学校送盒饭,小P一次最多可以携带M份盒饭.总共有N个学校来参加比赛,这N个学校的休息点在一条笔直的马路边一字排开,路的一头是小P取盒饭 ...
- 结对项目——图形界面实现与dll动态链接
先来一发软件截图~~~ 生成题目的界面 测评界面 第三块本来准备做一个文件历史记录的界面,但是由于时间不够,暂时还没做完. 图形界面的设计与实现 由于对传统的对话框风格不太满意,所以这次作业的图形界面 ...