指针碰撞和空闲列表

对于Java开发来讲,在虚拟机内存管理的帮助下,不须要为每一个新的对象在代码层面分配内存,回收内存,好比像C语言那样操做。因此在正常状况下,内存泄露和内存溢出等问题也不太容易出现。因此要是运行中的程序出现了内存泄露问题,排查仍是有必定困难。安全

Java堆是被全部线程共享的一块内存区域,主要用于存放对象实例,为对象分配内存就是把一块大小肯定的内存从堆内存中划分出来,一般有指针碰撞和空闲列表两种实现方式。并发

1.指针碰撞法
假设Java堆中内存时完整的,已分配的内存和空闲内存分别在不一样的一侧,经过一个指针做为分界点,须要分配内存时,仅仅须要把指针往空闲的一端移动与对象大小相等的距离。使用的GC收集器:Serial、ParNew,适用堆内存规整(即没有内存碎片)的状况下。post

2.空闲列表法
事实上,Java堆的内存并非完整的,已分配的内存和空闲内存相互交错,JVM经过维护一个列表,记录可用的内存块信息,当分配操做发生时,从列表中找到一个足够大的内存块分配给对象实例,并更新列表上的记录。使用的GC收集器:CMS,适用堆内存不规整的状况下。学习

内存分配并发问题线程

在建立对象的时候有一个很重要的问题,就是线程安全,由于在实际开发过程当中,建立对象是很频繁的事情,做为虚拟机来讲,必需要保证线程是安全的,一般来说,虚拟机采用两种方式来保证线程安全:指针

  • CAS: CAS 是乐观锁的一种实现方式。所谓乐观锁就是,每次不加锁而是假设没有冲突而去完成某项操做,若是由于冲突失败就重试,直到成功为止。虚拟机采用 CAS 配上失败重试的方式保证更新操做的原子性。
  • TLAB: 为每个线程预先分配一块内存,JVM在给线程中的对象分配内存时,首先在TLAB分配,当对象大于TLAB中的剩余内存或TLAB的内存已用尽时,再采用上述的CAS进行内存分配。

若是想多了,建立一个对象仍是挺麻烦的,须要这么多步骤,那么咱们在开发过程当中尽可能非必须的对象建立呢?对象

建立对象有如下几个要点内存

  1. 类加载机制检查:JVM首先检查一个new指令的参数是否能在常量池中定位到一个符号引用,而且检查该符号引用表明的类是否已被加载、解析和初始化过
  2. 分配内存:把一起肯定大小的内存从Java堆中划分出来
  3. 初始化零值:对象的实例字段不须要赋初始值也能够直接使用其默认零值,就是这里起得做用
  4. 设置对象头:存储对象自身的运行时数据,类型指针
  5. 执行<init>:为对象的字段赋值

学习前人笔记,记录一下!开发

参考:get

https://www.jianshu.com/p/eaef248b5a2c

http://www.javashuo.com/article/p-dbrhobli-es.html

相关文章
相关标签/搜索