文章目录
java基础知识
HashMap
HashMap是如何工作的
作者:阿进的写字台
HashMap底层是基于数组,数组中存储Node节点,发生碰撞时,采用拉链法,节点数小于8时形成链表,大于8时用红黑树。
Java 内存管理
内存管理
作者:CHEN川
JVM管理的内存分为两类,所有线程共享的数据区与线程隔离的数据区
内存分类
Method Area
存储已被虚拟机加载的类信息、常量、静态变量、JIT编译后的代码等数据。
Runtime Constant Pool
常量池被加载到内存之后的版本,运行期间产生的新的常量也可以放入运行时常量池。
常量池主要用于存放字面量和符号引用量。
Heap space
java堆可以分为新生代和老年代,新生代包括Eden、From Survivor,To Survivor。
Eden与Survivor的比值一般为8:1,新生对象在新生代Eden区中分配,当Eden区没有足够的空间进行分配时,则触发一次Minor GC,将对象Copy到Survivor区,如果Survivor区没有足够的空间来容纳,则会通过分配担保机制提前转移到老年代去。
Survivor区的对象经过若干次GC后仍然存活会置入老年代。
VMStack & Native Method Stack
虚拟机栈用于描述方法执行:每个方法执行的同时会创建一个栈帧用于存储局部变量表、操作数栈、动态连接、方法出口等信息。
public void sayHello(String name) {
System.out.println("hello " + name);
greet(name);
bye();
}
Program Counter Register
多线程中为了保证每个线程在切换后能恢复切换之前的程序执行位置,每个线程都必须有自己的程序计数器,互不干扰。
内存分配
内存分配的两种方式
- 指针碰撞
堆内存规整无碎片时使用
将用过的内存整合到一边,没用过的整合到一边,中间有一个分界指针,只需要向未分配的内存方向移动边界指针到对象内存需要的大小即可。 - 空闲碰撞
适用于堆内存不规整的情况。
虚拟机维护一个列表,列表记录的是可用的内存,分配的时候,找一块足够大的内存块划分给对象实例,然后更新列表。
内存分配并发问题
采用两种方式来保证线程安全:
- (CAS)乐观锁+失败重试
- TLAB:为每个线程在Eden区分配一块内存,给对象分配内存时,首先在TLAB分配,再采用CAS分配。
对象创建
内存与对象创建
作者:SnailClimb在csdn
对象创建的过程:
对象头
对象头中存放类的元数据信息,对象的哈希码,对象的GC分代年龄等信息
初始化
上面步骤执行完后,对象才会按照程序员的意愿进行初始化。
对象的访问定位
-
使用句柄
-
直接指针