名称 | 特征 | 作用 | 配置 | 异常 |
---|---|---|---|---|
栈区 | 线程私有,使用一段连续的内存空间 | 存放局部变量表、操作栈、动态链接、方法出口 | -XSs | StackOverflowError OutOfMemoryError |
堆 | 线程共享,生命周期与虚拟机相同 | 保存对象实例 | -Xms -Xmx -Xmn | OutOfMemoryError |
程序计数器 | 线程私有、占用内存小 | 指向当前线程正在执行的字节码指令行号 | 无 | 无 |
方法区 | 线程共享 | 存储类加载信息、常量、静态变量等 | -XX:PermSize -XX:MaxPermSize | OutOfMemoryError |
JDK 1.6下,会出现“PermGen Space”的内存溢出,
而在 JDK 1.7和 JDK 1.8 中,会出现堆内存溢出,并且 JDK 1.8中 PermSize 和 MaxPermGen 已经无效。
因此,可以大致验证 JDK 1.7 和 1.8 将字符串常量由永久代转移到堆中,并且 JDK 1.8 中已经不存在永久代的结论。
https://www.cnblogs.com/wangdaijun/p/8620008.html
通常将 CAS 用于同步的方式是从地址 V 读取值 A,执行多步计算来获得新 值 B,然后使用 CAS 将 V 的值从 A 改为 B。如果 V 处的值尚未同时更改,则 CAS 操作成功。
类似于 CAS 的指令允许算法执行读-修改-写操作,而无需害怕其他线程同时 修改变量,因为如果其他线程修改变量,那么 CAS 会检测它(并失败),算法 可以对该操作重新计算。
--------------------- 本文来自 jayxu无捷之径 的CSDN 博客 ,全文地址请点击:https://blog.csdn.net/ls5718/article/details/52563959?utm_source=copy
AtomicStampedReference类
-
AtomicStampedReference原子类是一个带有时间戳的对象引用,在每次修改后,AtomicStampedReference不仅会设置新值而且还会记录更改的时间。当AtomicStampedReference设置对象值时,对象值以及时间戳都必须满足期望值才能写入成功,这也就解决了反复读写时,无法预知值是否已被修改的窘境
Unsafe类存在于sun.misc
包中,其内部方法操作可以像C的指针一样直接操作内存
--------------------- 本文来自 sylarji 的CSDN 博客 ,全文地址请点击:https://blog.csdn.net/mmoren/article/details/79185862?utm_source=copy
1. ABA问题
2. 循环时间长开销大
3. 只能保证一个共享变量的原子操作AtomicReference
https://blog.csdn.net/Hsuxu/article/details/9467651
1. HashMap的原理,内部数据结构?
。底层使用哈希表(数组+链表),当链表过长会将链表转成红黑树以实现0(logn)时间复杂度内查找2.讲一下HashMap中put方法过程?
i.对Key求Hash值,然后再计算下标。ii.如果没有碰撞,直接放入桶中,
ill. 如果碰撞了,以链表的方式链接到后面,
iv. 如果链表长度超过阀值(TREEIFY _THRESHOLD==8),就把链表转成红黑树。V.如果节点已经存在就替换旧值
vi.如果桶满了(容量*加载因子),就需要resize.
3. HashMap中hash函数怎么是是实现的?还有哪些hash的实现方式?
i.高16bit不变,低16bit和高16bit做了一个异或i (n- 1) & hash -->得到下标
ill. 还有哪些Hash实现方式:可以参考之前的博客Effective Java学习笔记-- hashCode(
4. HashMap怎样解决冲突,讲一下扩 容过程,假如一个值在原数组中,现在移动了新数组,位置肯定改变了,那是什么定位
到在这个值新数组中的位置,。将新节点加到链表后,
容量扩充为原来的两倍,然后对每个节点重新计算哈希值。
。这个值只可能在两个地方,一一个是原下标的位置,另一种是在下标为<原下标+原容量>的位置。5. 抛开HashMap, hash冲突有那些解决办法?
。开放定址,链地址法
6.针对HashMap中某个Entry链太长,查找的时间复杂度可能达到O(n),怎么优化?
将链表转为红黑树, JDK1.8已经实现了。
http://ifeve.com/hashmap-concurrenthashmap-%E7%9B%B8%E4%BF%A1%E7%9C%8B%E5%AE%8C%E8%BF%99%E7%AF%87%E6%B2%A1%E4%BA%BA%E8%83%BD%E9%9A%BE%E4%BD%8F%E4%BD%A0%EF%BC%81/
首先第一部分执行的是父类的静态代码块—子类的静态代码块—主程序。这一部分都是执行一次,与建立多少对象没有关系。
第二部分new了一个父类对象,并调用了方法。执行了它的非静态代码块—构造函数—一般方法。
第三部分new了一个子类的对象,并调用了方法。执行顺序为父类的非静态代码块—父类的无参构造函数,然后是子类的非静态代码块—子类构造函数—子类的方法。
原文:https://blog.csdn.net/lwang_it/article/details/78545318?utm_source=copy