【JVM】第二章 Java内存区域

1、java内存管理的优势

相对于C语言需要开发人员自己手动的管理内存来说,java语言的自动内存回收机制是一大优势。但同时如果生产环境出现了内存溢出和泄露,就需要我们了解jvm的原理,以便更好的应用jvm提高性能和安全。

2、运行时数据区域(这是一个理论模型)

1)在说每个部分的作用之前说一下线程共享数据区和线程隔离数据区。

一个是共享就是这块区域是大家都可以用,一起分享的。

一个是线程隔离,说明它是基于线程存在的,每个线程都相互独立各不干扰。

 

  • 线程隔离数据区

2)程序计数器

当前线程所执行的字节码的行号指示器。

jvm的多线程是通过线程轮流切换并分配处理器执行时间,为了线程切换后能恢复到上一次所执行的位置。所以每条线程都有一个独立的程序计数器。

3)虚拟机栈

就是我们所说的栈空间。每个线程由栈桢组成。每个栈桢由四部分组成:

局部变量表:方法的参数和方法内部的局部变量内存分配就在这里。

操作数栈:是一种stack结构。后进先出,通过压栈和出栈配合变量表进行相应的运算。

动态连接:这是针对java的特性设计的,只有只有在运行时才能知道它的直接引用地址在哪里。

返回地址:当方法正常或异常退出的时候,返回方法被调用的位置。

4)本地方法栈

与虚拟机栈发挥的作用相似,区别就是虚拟机栈为虚拟机执行java方法服务,而本地方法栈则为虚拟机使用Native 方法服务。

 

  • 线程共享数据区

5)堆

java虚似机管理的内存中最大一块。

所有线程共享的一块内存区域,在虚拟机启动时创建

此内存区域唯一目的就是存放对象实例。

所有的对象实例以及数组都要在堆上分配

Young区:S0+S1 、Eden (新生代)

Old区 (老年代)

 

6)方法区(非堆区、永久代)

所有线程共享

它用于存储已被虚拟机加载的类信息、常量、静态变量、即时编译后的代码等数据

CCS压缩指针:针对64位操作系统想使用32位的压缩地址表示。默认是开启的。

CodeCache: 存放 JIT编译后的代码。(特殊的操作指令集)

 

7)运行时常量池

方法区的一部分。class文件中除了类的版本、字段、方法、接口等信息外,还有一项就是常量池。用于存放编译期生成的各种字面量和符号引用。

 

3、对象创建(普通java对象)

1)当虚拟机机遇到一条new的指令时,首先它会去常量池中能不能定位到这个类的符号引用,并检查这个类是否被加载过。(见类加载过程分析)

2)检查通过之后,在Eden 区分配内存。如果是大对象可能分配在Old区。有参数可以配置,一般我们不用管

3)内存分配后,将内存空间都初始化为零

4)设置对象头。(哪个类的实例,类的元数据信息、对象hash、对象GC分代年龄等信息)

5)执行<init>方法进行初始化。

 

4、对象的访问

通过直接指针访问对象

这是一个操作数栈与堆之间对象访问图。可以看出在操作数栈本地变量表中一个reference类型它指向的一个分配在java堆空间的对象地址。

对象实例数据:对象头、实例数据(全局变量)、对齐填充(不够8个字段的进行填充)

对象类型数据:类信息、常量、静态变量、jit编译的代码

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值