JVM学习笔记(1)-虚拟机内存

1.Java内存分布

Java程序运行的时候会向操作系统申请内存,这部分内存称为虚拟机内存,这部分内存包含以下几个区域




线程共有部分有:方法区和堆,这里是主要涉及到多线程同步问题的区域

线程私有部分:虚拟机栈,本地方法栈,程序计数器

(1)方法区:线程共享,主要用来存放虚拟机加载的类信息、常量、静态变量。也称之为永久区,设置参数有 -XX:MaxPermSize       -XX:PermSize

(2)堆区:线程共享(大多数的线程同步出现在这里),主要存放对象实例,是垃圾收集器管理的主要区域,可以称为GC堆。由于现有的垃圾收集器多采用分代收集算法,堆中去区域可以按分代来细分:新生代和老年代。新生代还可以细分为:Eden,From Servivor,To Servivor。从内存分配的角度还可以划分为线程私有的堆(分配缓冲区 TLAB: Thread Local Allocation Buffer)。设置参数有 -Xms  -Xmx  -Xmn

(3)虚拟机栈:线程私有,主要由栈帧组成,用于存放局部变量表、操作数栈、动态链表、方法出口信息等。每个方法的调用都对应一个栈帧的出栈和入栈。

局部变量表存放了编译期间的多种数据类型(8种基本数据类型和引用类型)

(4)本地方法栈:线程私有,主要服务于Native方法,和虚拟机栈类似,不同的是虚拟机栈服务于Java方法

(5)程序计数器:线程私有,存放字节码指令的地址,记录线程执行到哪一步的标识。若线程正在执行Java方法,则记录的是正在执行虚拟机字节码指令的地址;若线程正在执行Native方法,则为空。此区域是唯一没有OutOfMemoryError的情况发生的区域


(6)运行时常量池:属于方法区的一部分,用于存放编译期间生成的各种字面量和符号引用,比如int  a=25;

(7)直接内存:这部分内存不是JVM的内存。java nio引入了Channel与缓冲区Buffer的模式,直接调用Native方法分配堆外内存,通过存储在java堆中的DirectByteBuffer对象作为这块对象的引用进行操作,可以显著的提高性能


2.对象的创建

java对象创建通常通过new关键字去实现,虚拟机遇到new关键字时,首先回去常量池中查找是否有该对象的符号引用,并检查该类的符号引用是否已被加载、解析、初始化;如果没有则执行类加载,在内加载后开始为对象分配内存。


3.内存分配的方式

(1)指针碰撞:适用于内存大小规整的,连续的,中间没有碎片。在内存中,已使用的内存在一边,未使用的内存在一边,中间有一个指针作为分界点的指示器,分配内存的时候只需把这个指针向空闲的那部分移动即可;在使用Serial,ParNew等带整理算法收集器的时候采用指针碰撞的形式进行分配

(2)空闲列表:使用于内存不规整,已使用的内存和未使用的内存交杂,此时指针碰撞时没法实现的,需要有一个列表记录那些内存是可用的,这块列表叫“空闲列表”;在需要分配内存的时候首先在空闲列表中找一块足够大的空间,同时更新空闲列表。在使用CMS垃圾收集器的时候(使用的是标记清除算法)使用空闲列表方式分配内存


在分配内存移动指针的过程中,有可能指针还没来得及修改用原来的指针有分配了一块内存的情况,此时由两种形式去解决,

(1)对分配内存的空间动作进行同步处理,实际上虚拟机采用了CAS配上失败充实的方式保证更新操作的原子性

(2)吧内存的划分按线程划分到不同的空间,即每个线程预先分配一小块内存,称为本地线程分配缓冲(TLAB),当那个线程需要分配内存大的时候就在那个缓冲区中分配,当TLAB分配完需要重新分配TLAB的时候才需要同步,使用 -XX:+/-UseTLAB 来设定


4.对象的内存布局

对象在内存中的存储布局可以分为三块区域:对象头,实例数据,对齐填充

(1)对象头:包含两部分信息,一部分用于存储对象自身的运行数据,如哈希码、GC分代年龄、锁状态标识,线程持有的锁,偏向线程ID,偏向时间戳等这部分数据在32位和64位虚拟机(未开启指针压缩)中分别为32bit和64bit;对象头的另外一部分是指类型指针,即对象指向其类元数据(方法区中)的指针,通过这个指针可以确定这个对象是哪个类的实例;对于Java数组对象头中必须还有一块记录数组长度的数据,因为Java对象可以通过元数据确定Java对象的大小,但是Java数组是没法通过元数据确定数组大小的;

(2)实例数据:这部分是真正存放对象数据的地方

(3)对齐填充:不是必然存在的,没有特定含义起到占位符的作用,HotSpot虚拟机要求对象起始地址必须是8字节的整数倍,如果未达到则需对齐填充





  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值