讲道理,这是我第四遍看这本书了,不过之前有些知识点印象不深,现在记录一下。
1.对象的创建
为新生对象分配内存的两种方式
- 指针碰撞
- 一边是空闲的内存 一遍是已经使用的内存,中间一个指针作为标志,分配内存的时候就把指针往空闲内存移动一段和对象大小相同的距离 指针碰撞的前提是内存规整,一般使用复制清除法的收集器就是使用这种方法,比如Serial,ParNew.
- 空闲列表
- 维护一个记录内存中空闲块的列表,要分配内存时就从列表中找出一块适合大小的内存块 CMS这种基于标记清除算法的收集器使用这种算法
划分内存时保证线程安全的两种方法
并发情况下划分内存也不是就是线程安全的,很有可能出现给对象A分配内存时,在指针还未来得及修改的时候,对象B又使用了原来的指针分配内存
解决方法有两种:
- 对分配内存空间的动作进行同步操作
- JVM默认使用的CAS加失败重试的方法保证更新操作的原子性
- 使用本地线程缓冲区TLAB
- 每个线程都分配一块TLAB 要分配内存的线程在自己的TLAB上进行分配 可使用参数
-XX:+/-UseTLAB
来设置
- 每个线程都分配一块TLAB 要分配内存的线程在自己的TLAB上进行分配 可使用参数
创建对象的流程
分配内存空间—>除对象头外的内存空间设置为零值—>在对象头中设置对象的元数据信息,GC分代年龄以及哈希码等信息—>执行<init>
方法把对象按照程序意愿初始化