• JVM(一)内存分配


     方法区:

    ①存储被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码数据   

    ②又称为永久代,仅对于Hotspot来讲,JRockitIBM J9里面没有永久代的概念,1.8以后是元空间,直接使用的是外存

    ③垃圾回收再这一部分比较少,主要是对废弃常量的无用类的回收。

    ④运行时常量池也在这一部分。Class文件中除了类的版本、字段、方法、接口等描述信息以外,还有一项是常量池(Class文件常量池)用于存放编译生成的各种字面量和符号引用。 注意:运行时常量池和Class文件常量池

    ⑤无法分配内存时,OutOfMemory

    ⑥运行时常量池和Class文件常量池,Java语言并不要求常量一定在只能在编译期生成,也就是说并非预置入Class文件常量池的内容才能进方法区的运行时常量池,运行期间也可以,比如String.intern()方法;

      常量池(运行时常量池和class文件常量池)

    ①每一项常量都是一个表   

    ②包含Class文件中及其子结构中所有的字符串常量、类、接口名、字段名和其他常量。

    ③主要存放了两大类常量:字面量和符号引用。

    ④字面量:所有的文本字符串和声明为final的变量值

    ⑤符号引用:类和接口的全限定名;字段的名称和描述符;方法的名称和描述符可以理解为Class的资源仓库。

      ①几乎所有的对象实例和数组都在这分配内存  

      ②垃圾回收的主要区域,GC

      ③没有内存分配,没法扩展,出现outofMemoryError异常

    虚拟机栈

      局部变量表 :  

        ①方法参数(paramOne)、局部变量(tempParam)、对象引用(tempObject,returnAddress(指向字节指令的地址)

        ②编译阶段就确定的大小,在进入一个方法时,不会改变局部变量表的大小

        ③通过索引的方式去访问数据

       操作数栈:又一个栈,方法操作的栈。

      动态链接:

        ①每个栈帧都包含一个方法区中运行时常量池的引用,持有这个引用是为了支持方法执行过程中的动态链接。

        ②因为常量池中持有大量的符号引用,其中一部分引用在类加载期间会转化为直接引用,另一部分在运行时转化为直接引用,所以虚拟机栈的动态链接作用可以说是为了 在运行时将符号引用转化直接引用

      方法返回地址  

         ①一个方法退出有两种方式:一是遇到返回指令;二是遇到异常;

        ②当前栈帧出栈,将信息返回给上层调用的方法。

    本地方法栈

      虚拟机栈类似,只不过作用与本地方法。

     jvm内存分配相关知识

       一、内存分析

         Object o = new Object();

         ①涉及到三个内存区域:虚拟机栈的局部变量列表、堆、方法区

          o-->局部变量表

               new Object()-->实例对象放在堆中,

        堆中还必须包含此对象类型的信息(如对象类型、父类、实现接口、方法),它需要去方法区中找这部分信息。

       二、问题:对象的引用通过什么方式去定位堆中对象?

         ①句柄池和直接使用指针

         HotSpot使用直接使用指针定位

       三、内存溢出和测试方法

          Java堆:无限new 对象,保存到List

          ②方法区: a、测试方法区中的非常量池部分 :生成大量的动态类。

                 b、测试常量池:String.intern()产生不同的String实例,在List中保存。

             ③虚拟机栈 :    a、单线程:递归调用--stackOverFlowError

                 b、多线程:无限创建线程

       四、符号引用(类似于java.lang.Object的符号)

         ①一组符号,任何形式的字面量,在使用时可以无歧义定位到目标即可

         ②在Class文件中以CONSTAN_Clas_infoCONSTANT_Fieldref_infoCONSTANT_Method_info等类型常量出现,

         ③符号引用与内存布局无关。

          Java中,一个Java类将会被编译成一个Class文件,在编译过程中,Java类并不知道所引用类的实际地址,因此只能用符号引用代替,比如org.simple.People引用了org.simple.Language类,在编译时People并不知道Language类的实际内存地址,  因此只能用符号org.simple.Language(实际上是以CONSTANT_Class_info的 常量)来表示的Language的地址。

        五、直接引用(地址)

        ①直接指向目标的指针

             ②相对偏移量,指向实例变量、实例方法的都是偏移量。

             ③能够定位到目标的句柄。

             ④与虚拟机的内存布局有关

         各种虚拟机实现的内存布局不太一样,符号引用与内存布局无关,但是他们所接受的符号引用都是一样的,因为符号引用的字面量形式明确定义在了java虚拟机规范的Class文件格 式中,

        但是直接引用就有关了,同一个符号引用在不同的虚拟机上翻译出来的直接引用都不太一样,如果有了直接引用,那引用的目标必定已经被加载到内存中了

    天助自助者
  • 相关阅读:
    VS 文件编码
    CSS中强大的EM 弹性布局
    编辑器【updating】
    下一代Jquery模板JsRender
    HTML 特殊符号编码对照表
    ASP.NET 文摘 [updating]
    Html5/Html CSS3/css 文摘 [updating]
    在Sublime Text 2中设置任意扩展名文件的默认语法
    Delphi笔记Indy10.5.5 IdTcpServer 与 IdTcpClient Demo 服务器端
    基于silverlight的工作流编辑器
  • 原文地址:https://www.cnblogs.com/ZeGod/p/9964731.html
Copyright © 2020-2023  润新知