返回博主主页

java虚拟机

一、java虚拟机运行时数据区域主要分为:

1.程序计数器(PC寄存器)

2.java虚拟机栈:

  局部变量表、操作数栈、动态链接、方法出口等。(详见——)

3.本地方法栈(JNI):

4.堆:

5.方法区:

  类信息、常量、静态变量、即时编译器编译后的代码。

  (jdk1.8 hotspot把类信息放在元空间,元空间一道本地内存;常量和静态变量移到了堆中

  数据段:类变量、常量

  代码段:方法的定义(堆中会留有一个地址值与方法区的值对应)

  全局变量(或者叫做字段,属性)在全局区(静态区)(我是把全局变量(成员变量)与实例变量等价,方法里的变量叫做局部变量。全局限量有默认值,局部变量没有默认值;或者全局变量、实例变量都叫实例变量,自己弄清楚就行)

    (1)全局变量既不在堆中,也不在栈中,而是在全局区(静态区),全局变量的存储和静态变量是在一起的。(我的理解:全局变量与静态变量都是类的字段/属性,用Static修饰的叫做静态变量,但是类的不同对象共享一个静态变量,累的不同对象各自有自己的一个全局变量)。代码举例如下:(参见——————)

    (2)初始化的全局变量和静态变量在同一块区域“数据段”;未初始化的全局变量和静态变量在相邻的另一块区域“数据段中的BSS段:特点是可读可写;在程序执行前BSS段会清0”

6.运行时常量池:

class文件中除了有类的版本、字段、方法、接口等描述等信息外,还有一项信息是常量池。

Class 文件中的常量池(**编译器生成的字面量和符号引用**)会在类加载后被放入这个区域。

除了在编译期生成的常量,还允许动态生成,例如 String 类的 intern()。eg:"hello".intern(),但是常量是若已经存在了“hello”,就不插入。

运行时常量池是方法区的一部分,注意jdk1.8中hotspot虚拟机实现方法区时候,是把方法区放在了元空间,运行时常量池挪到了堆中,见下图

JDK 版本方法区的实现运行时常量池所在位置字符串常量池所在位置
JDK6 PermGen space(永久代) PermGen space(永久代) PermGen space(永久代)
JDK7 PermGen space(永久代) PermGen space(永久代) Heap(堆)
JDK8 Metaspace(元空间) Metaspace(元空间) Heap(堆

注意:HotSpot实现的运行时数据区和Java虚拟机规范定义的还是有所不同的,

  ①、将**Java虚拟机栈和本地方法栈合二为一;

  ②、元数据区取代了方法区,并且元数据区不在Java虚拟机中,而是在本地内存中

  ③、运行时常量池方法区中移到了

方法区是一个 JVM 规范,永久代与元空间都是其一种实现方式。在 JDK 1.8 之后,原来永久代的数据被分到了堆和元空间中。静态变量和常量池等放入堆中,元空间存储类的元信息。

7.直接内存

  在 JDK 1.4 中新引入了 NIO 类,它可以使 用 Native 函数库直接分配堆外内存,然后通过 Java 堆里的 DirectByteBuffer 对象作为这块内存的引用进行操作。这样能在一些场景中显著提高性能,因为避免了在堆内存和堆外内存来回拷贝数据。

 

posted @ 2020-08-31 17:13  懒惰的星期六  阅读(152)  评论(0编辑  收藏  举报

Welcome to here

主页