JVM内存区域

Posted joecqupt

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了JVM内存区域相关的知识,希望对你有一定的参考价值。

JVM 内存划分

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

对象的分配

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

分配内存 线程安全问题:

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

对象内存中的信息布局

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

对象的定位:

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

OutOfMemoryError

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

  • 内存泄露 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,那么可以考虑检查是不是这一方面的问题

以上是关于JVM内存区域的主要内容,如果未能解决你的问题,请参考以下文章

JVM的内存区域

JVM的内存区域

JVM系列 - JVM内存区域详解

JVM调优—内存区域

JVM内存区域参数配置

JVM的内存区域划分