java虚拟机内存管理

Posted 征途2

tags:

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

  • 虚拟机运行时数据区

    • 线程共享
      • java Heap
        •  java heamp是java虚拟机可配置管理的最大内存区;唯一的目的用于存储实例对象,所有线程共享;
        • GC堆,回收技术主要采用分代收集算法;java Heap细分为:新生代、老生代;划分本身与存放内容无关;无论怎么划分,都是为了更好的分配和回收内存;
        • 逻辑上连续,物理上未必连续;
        • 利用-Xms、-Xmx进行配置,无法分配及扩展时,将会抛出OutOfMerroyError错误;
      • method area
        • 存储对象:虚拟机加载的类信息、常量、静态变量、JIT编译器编译后的代码
        • alias name: Non-Heap
        • HotSpot虚拟机,Permanent Generation(永久代),实际上两者并不等价,将GC扩展到方法区;
    • 线程隔离
      • native method stack
      • program counter register
        • 线程私有;
        • java虚拟机多线程通过线程轮流切换并分配处理器执行时间;
        • 多线程轮流切换,必然需要在某刻恢复线程在上次执行的执行地址;例如一个线程在执行一个方法,计数器记录就是线程执行的虚拟机字节码指令的地址;如果是Native方法,那么计数器的值为空(undefined)
        • 唯一一个无OutOfMemoryError的内存
      • vms stack
    • 直接内存
      • direct memory, 并非是虚拟机运行时数据区的一部分;
      • NIO(new input/output), channel+buffer新型IO,利用Native函数库直接分配堆外内存;利用存储在java-heap中的DirectByteBuffer对象对该块内存进行直接引用操作;优点是避免在java-heap和native-heap之间进行来回复制数据
      • OutOfMerroyError错误;
  •  对象

    • 内存分配方式
      • 指针碰撞(bump the pointer)---ParNew、Serial
      • 空闲列表(Free List)  --- CMS(Mark-Sweep)
    • 决定条件
      • 垃圾收集器是否带有压缩整理==>java-heap是否规整
    • 内存分配策略
      • 目的:解决冲突问题
      • 方法一:CAS + 错误重试===>保证更新操作的原子性
      • 方法二:线程在不同的空间预分配内存(java-heap),预分配内存称之为TLAB(Thread Local Allocation Buffer),那个线程需要分配内存,就在那个线程的TLAB上分配,只有TLAB用光后分配新的TLAB时,才需要同步锁定;虚拟机是否使用TLAB,通过-XX:+/-UseTLAB参数配置;
    • 内存布局
      • header、Instance Data、Padding(对齐填充)
      • header: 对象的HashCode\偏向线程ID\GC分代年龄\锁状态标志\类型指针(对象指向它的类元数据的指针)
      • Padding无真实意义;保证数据长度是8字节的整数倍
      • Instance Data: 父类和子类可能会交叉存储,较小的子类变量可能会插入到父类变量的空隙之中;相同长度的字段总被分配到一起,如:shorts/chars、longs/doubles
    • 对象访问
      • 句柄、直接指针
      • 区别
        • 句柄方式访问数据 --- reference(句柄地址)-->句柄池(存放数据指针)--->对象指针-->数据
          • 优势:数据移动,reference不用动
        • 直接指针 ----reference(对象指针地址)-->对象指针-->数据
          • 优势:访问数据块
  •  JVM Error

    • java-heap配置
      • -Xms(堆最小), -Xmx(堆最大)
        • 不可扩展:设置相同
        • -XX:+HeapDumpOnOutOfMemoryError: 当出现内存溢出异常时,Dump出当前的内存堆的存储快照
    • 分类
      • 堆溢出
        • memory leak(内存泄露)
        • memory overflow(内存溢出)
      • 栈溢出(虚拟机、本地方法)
        • -Xss决定
        • 出现场景
          • 线程请求栈深度>虚拟机允许深度  -->StackOverfolwError
          • 虚拟机在扩展栈时未申请到足够内存 -->OutOfMemoryError
      • 方法区、运行时常量池
        • -XX:PermSize -XX:MaxPermSize
        • String.intern(),Native方法,作用:如果常量池中有对应String对象,那么返回;如果没有,将对应的字符串放入常量池;具体用法:String.ValueOf(i++).intern()
      • 直接内存
        • -XX:MaxDirectMemorySize,如果不指定,默认等于-Xmx取值相同

以上是关于java虚拟机内存管理的主要内容,如果未能解决你的问题,请参考以下文章

Java虚拟机内存区域堆(heap)的管理

JVM -- Java虚拟机自动内存管理机制(运行时数据区域HotSpot虚拟机对象探秘)

JVM -- Java虚拟机自动内存管理机制(运行时数据区域HotSpot虚拟机对象探秘)

浅析虚拟机内存管理模型

java虚拟机内存管理

探秘Java虚拟机——内存管理与垃圾回收(转)