jvm基础篇(一)

基本问题

    • 介绍下java内存区域(运行时数据区)
    • Java对象的创建
    • String类和常量池

  1、概述

    对于Java程序员来说,在虚拟机自动管理机制下,不在像C/C++那样为一个new操作去写对应的delete/free操作。不容易出现内存泄露和内存溢出问题。

    正是因为Java程序员把内存泄露和内存溢出问题交给Java虚拟机,一旦出现内存泄露和内存溢出的问题,如果不了解Java虚拟机是怎么使用内存的,那

    么排查错误将会是一个非常间距的问题。

  2、运行时数据区

    Java虚拟机在运行Java程序过程中会把它管理的内存分成若干不同区域。

              

    这些组成部分一些是线程私有的,一些是线程共享的。

    线程私有的:

      程序计数器

      虚拟机栈

      本地方法栈

    线程共享的:

      堆

      方法区

  3、对象的创建

    对象的创建分为5步

      

    3.1 类加载检查

      虚拟机遇到一条New指令时,首先将去检查这个指令的参数是否能在常量池中定位到这个类的符号引用,并且检查这个符号引用

        代表的类是否被加载或初始化过,如果没有,那必须先执行相应的类加载过程。

    3.2 内存分配

      类加载检查之后,接下来虚拟机将为新生对象分配内存。对象所需的内存大小在类加载完成后便可确定,为对象分配空间也就等同

      于把一块确定大小的内存从Java堆中划分出来。

    3.3 初始化零值

      内存分配完成后,,虚拟机需要将分配到的内存空间都初始化为零值(不包括对象头),这一步操作保证了对象的实例字段在Java代

      码中可以不赋值就直接使用,程序能访问到这些字段的数据类型所对应的零值。

    3.4 设置对象头

      初始化零值完成后,虚拟机要对对象进行必要的设置,例如这个对象是哪个类的实例?如何才能找到类的元数据信息、对象的哈希值

      对象的GC年代等信息。这些信息存放在对象头中。

    3.5 执行init方法

      在上面工作完成之后,从虚拟机的角度来看,一个新的对象就产生了,但从Java角度来看,对象的创建才刚开始。<init>方法还没有

      执行,所有的字段还都为零。所以一般来说,执行完new之后会接着执行<init>方法,把对象按照程序员的意愿进行初始化出来,这样

      才算创建出一个真正的可用对象。

  4. 对象的内存布局

    在Hotspot虚拟机中,对象在内存中的布局可以分为3块区域:对象头、实例数据、对齐填充。

      对象头包含两部分,第一部分用于存储对象自身的运行数据(哈希吗、GC分代年龄、锁状态标志等),另一部分是类型指针,即对象指向它

      的元数据的指针,虚拟机通过这个指针确定对象是哪个类的实例。

      实例数据部分是对象真正存储的有效信息,也是程序中所定义的各种类型字段内容。

      对齐部分不是必然存在的,也没有特别的含义,仅仅起占位作用。

    

  5. String类和常量池

    

    这两种方式的创建是有区别的,第一种是在常量池中拿对象,第二种是直接在堆内存空间创建一个新的对象。

          

    

猜你喜欢

转载自www.cnblogs.com/blue327/p/10996334.html
今日推荐