JVM内存区域

JVM 内存划分

    • 虚拟机栈
    • 本地方法栈
  • 方法计数器
  • 方法区

对象的分配

  • 指针碰撞
  • 空闲列表 (√)

分配内存 线程安全问题:缓存

  • 分配动做处同步---实际上采用CAS保证分配的原子性
  • TLAB 本地线程分配缓存

对象内存中的信息布局安全

  • 对象头
    • Mark word (根据对象状态复用此部分空间)
      • hashcode
      • GC分代信息
      • 锁状态信息
      • 线程持有的锁
      • 偏向线程ID
      • 偏向时间戳
      • .....
    • 类型指针(对象指向它的类元数据的指针,虚拟机能够经过这个指针来肯定这个对象是哪个类的实例)
  • 实例数据
  • 对齐填充(对齐填充并非必要的,只是vm要求对象的大小必须是8的整数倍,当实例数据没有对齐时,须要填充来补全。)

对象的定位:框架

  • 使用句柄
    • 优势 :对象被移动 只会改变句柄中的的指针
    • 缺点 :多了一次查找
  • 直接指针访问 (√)
    • 优势 : 速度快

OutOfMemoryError

  • 内存溢出 out of memory,是指程序在申请内存时,没有足够的内存空间供其使用,出现out of memory;jvm

  • 内存泄露 memory leak,是指程序在申请内存后,没法释放已申请的内存空间,一次内存泄露危害能够忽略,但内存泄露堆积后果很严重,不管多少内存,早晚会被占光。布局

StackOverflowError

  • 若是线程申请的栈的深度大于虚拟机所容许的最大深度,抛出StackOverflowError异常
  • 若是虚拟机在扩展栈时候,没法申请到足够的内存空间。抛出OutOfMemory异常

方法区与运行时常量溢出

  • jdk 1.6 以及以前的版本可使用 String.intern() 方法
    • String.intern() 方法的是做用是:若是字符串常量池中已经含有此字符串那么返回此字符串的,若是不包含此字符串 那么将此 字符串实例 复制到字符串常量池中。
    • jdk 1.7 版本不会将字符串 复制 字符串实例,只会记录此字符串的引用。
  • jdk 1.7 只会可使用 反射,或者字节码操做框架产生大量的Class对象来形成 方法区溢出

本地直接内存溢出 -XX:MaxDirectMemorySize=10M;

  • 可使用 UnSafe类 (没有试验成功过)

若是发生了内存溢出异常,可是dump文件看不出明显的异常,而且dump文件很小,而程序中又直接或者间接使用了NIO,那么能够考虑检查是否是这一方面的问题线程