2.jvm内存管理

一、整体架构

五个部分


image.png

线程私有:右侧部分,虚拟机栈、本地方法栈、程序计数器
线程共享:左侧部分,堆,方法区

五个模块:类装载子系统、运行时数据区、执行引擎、本地方法接口、垃圾收集模块


image.png

(class字节码文件— 加载(选择类加载器)—连接—初始化)

二、运行时内存

2.1程序计数器

线程私有的,记录字节码行号(类似寄存器的程序计数器)。可以告诉我们每一个线程执行到了哪一个位置。
pc寄存器所在的线程失去执行权时会记录下一条指令对应的编号,在线程重新获取执行权时执行。

2.2虚拟机栈

线程私有,内存连续。每调用一个方法都是入栈。虚拟机栈包含栈帧(方法A),每个方法压栈之后会有一个新的栈帧,栈帧内包含局部变量表、操作栈,动态链接、方法返回地址,虚拟机栈中有很多栈帧(方法)。

  • -Xss1m:设置虚拟机栈的大小
  • 局部变量表:存放方法参数、方法内声明的局部变量。包括8种基本类型、对象引用、returnAddress(指向一条字节码指令的值)
  • 操作数栈:随着方法执行和字节码指令的执行,会从局部变量表或对象实例的字段中复制常量或变量写入到操作数栈,再随着计算的进行将栈中元素出栈到局部变量表或者返回给方法调用者,也就是出栈/入栈操作
  • 动态连接:指向运行时常量池的符号引用,比如#2这个符号引用代表了运行时常量池中的某个类和某个方法。持有这个引用的目的是为了支持方法调用过程中的动态链接(Dynamic Linking)
public class StackDemo2 { 
    public static void main(String[] args) { 
        int i = 1; 
        int j = 2; 
        int z = i + j; 
    }
  }

如上,i,j,z和它们的值一开始存在局部变量表中,当程序计数器指向i=1这行的时候,将1从局部变量表复制到操作数栈中,接着指向j=2,将2复制到操作数栈,再然后指向j+i,得到结果3,将结果3放入操组数栈并且返回保存到局部变量表

  • 方法返回地址:调用该方法的pc寄存器的值。比如方法A调用完成,返回值是调用该方法的指令的下一条指令的地址的值。方法报错出现异常,返回的是异常的信息

2.3本地方法栈

线程私有,为native方法提供服务。在虚拟机栈调用本地方法的时候提供调用服务

2.4堆

线程共享,内存不连续,包含新生代和老年代。
堆空间大设置:最大:Xmx20m 最小:Xms

  • 线程共享

  • 是jvm管理的内存最大的一块区域。

  • 有一小块区域,叫线层缓冲区,thread local allocation buffe,是私有的

  • 堆中基本上存储所有对象,逃逸的可能,对象有可能放在方法区。

  • 垃圾回收器主要管理的区域
    jdk7堆空间分类


    image.png

    perm在jdk8以后被移除,因为方法区被元空间取代
    jdk8堆空间分类


    image.png
  • 对象分配过程:
    对象创建,放入年轻代的伊甸园区,伊甸园填满,触发minor gc,将无引用的对象清除,剩余对象放入幸存者0区,如果再次gc,会将幸存的还存在引用的对象放入幸存者1区,反复15次,进入老年代,老年代内存不足的时候,进行major gc,如果还是内存不足,full gc,还放不下就报错。

  • 新生代收集(Minor GC / Young GC): 只是新生代的垃圾收集

  • 老年代收集 (Major GC / Old GC): 只是老年代的垃圾收集 (CMS 的 majirGC 单独回收老年代,其它的major相当于full)

  • 混合收集(Mixed GC):收集整个新生代及老年代的垃圾收集 (G1 GC会混合回收, region区域回收)

  • 整堆收集(Full GC):收集整个java堆和方法区的垃圾收集器

2.5元空间

1.8开始,元空间取代了方法区,位于本地内存中而不是jvm虚拟机中。
元空间中存放了原本存在于方法区中的类的元信息,而方法区中的静态变量和常量池并入堆中。
元空间好处:

  • 方法区存放的信息导致其空间大小不容易确定,很容易出现内存溢出
  • 提升类元数据的独立性
  • 降低gc复杂度

区别
元空间metaspace可以在运行时扩展。
元空间metaspace是本机内存的一部分,而permGen是堆的一部分。

2.6方法区

线程共享,被虚拟机栈加载过的数据保存在方法区,比如类的信息、常量,静态变量。包含永久代。
去除后,方法区的内容被瓜分:(类静态变量、字符串常量池好像在jdk7就已经转移到堆了)

  • 类信息——元空间
  • 类静态变量、字符串常量池——堆

Java7及以前版本的Hotspot中方法区位于永久代中。同时,永久代和堆是相互隔离的,但它们使用的物理内存是连续的。

2.7运行时常量池

运行时常量池vs常量池
  • 常量池位于字节码文件中,用来存放编译期间生成的各种字面量与符号引用。常量池,可以看做是一张表,虚拟机指令根据这张常量表找到要执行的类名、方法名、参数类型、字面量等类型。
  • 运行时常量池位于方法区中,是常量池在运行时的表现形式
理解为字节码中的常量池 Constant pool 只是文件信息,它想要执行就必须加载到内存中。而Java程序是靠
JVM,更具体的来说是JVM的执行引擎来解释执行的。执行引擎在运行时常量池中取数据,被加载的字节码常量池
中的信息是放到了方法区的运行时常量池中。
它们不是一个概念,存放的位置是不同的。一个在字节码文件中,一个在方法区中。

2.8直接内存

在JDK 1.4中新加入了NIO(New Input/Output) 类, 引入了一种基于通道(Channel) 与缓冲区 (Buwer) 的I/O方式, 它可以使用Native函数库直接分配堆外内存, 然后通过一个存储在Java堆里面的 DirectByteBuwer对象作为这块内存的引用进行操作。 这样能在一些场景中显著提高性能, 因为避免了 在Java堆和Native堆中来回复制数据。

类信息:





反射获取method、field、interface等都是从private transient volatile SoftReference<Class.ReflectionData<T>> reflectionData; 这个变量中获取,在java.lang.Class中被声明为类变量。

字符串常量池(String Pool)

  • java6:
    • 存在于永久代中。
    • 字符串常量池保存的是字符串常量。
  • java7:
    • 转移到了堆中。
    • 字符串常量池存的是字符串常量和堆内的字符串对象的引用。

静态常量池(class文件常量池)

  • 用于存放编译器生成的各种字面量(Literal)和符号引用(Symbolic References)。
    • 字面量:文本字符串int long 等基本类型和被声明为final的常量值等。
    • 符号引用:是一组符号来描述所引用的目标,符号可以是任何形式的字面量一般包含以下三种:
      1. 类和接口的全限定名:例如对于String这个类,它的全限定名就是java/lang/String。
      2. 字段的名称和描述符:这里的字段就是类或者接口中声明的变量。
      3. 方法的名称和描述符:这里的描述符是方法的参数类型+返回值类型。
  • 静态常量池其实就是编译后的class文件里的一部分内容。

运行时常量池

  • 当类加载到内存中后,jvm就会将静态常量池中的内容存放到运行时常量池中。
  • 运行时常量池中的字符串在从静态常量池加载时
    • 会先去String Poll中查询此此字符串在String Poll中的引用
    • 如果没有则在String Poll中创建此字符串然后返回其引用
    • 用返回的引用替换运行时常量池的字符串
  • 运行时常量池是全局共享的,多个类共用一个运行时常量池。并且class文件中常量池多个相同的字符串在运行时常量池只会存在一份

在JDK1.8中,使用元空间代替永久代来实现方法区,但是方法区并没有改变,变动的只是方法区中内容的物理存放位置。正如上面所说,类型信息(元数据信息)等其他信息被移动到了元空间中;但是运行时常量池和字符串常量池被移动到了堆中。但是不论它们物理上如何存放,逻辑上还是属于方法区的。

元空间的本质和永久代类似,都是对JVM规范中方法区的实现。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,670评论 5 460
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,928评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,926评论 0 320
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,238评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,112评论 4 356
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,138评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,545评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,232评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,496评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,596评论 2 310
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,369评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,226评论 3 313
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,600评论 3 299
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,906评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,185评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,516评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,721评论 2 335

推荐阅读更多精彩内容