白话Java基础—JVM内存结构

白话Java基础系列—JVM内存结构

本系列呢,主要将我理解的Java基础内容,以比较白话的方式,解释出来,希望能帮助大家快速的理解一些概念。

本小结将分享下 JVM内存结构

一、 什么是JVM ?

JVM 是 JRE(Java Runtime Enviroment)的一部分, 它是一个虚拟的计算机,通过在实际计算机上仿真模拟计算机的各种功能来实现的。有完善的硬件架构, 如处理器、堆栈、寄存器等,还具有指令系统。

主要工作是解释自己指令集(字节码)映射成本地CPU指令集或OS的系统调用。(翻译成本地计算机可识别的指令集,并去调用)

二、 JVM内存结构

参考文档: http://47.103.216.138/archives/80, 图片直接引用了 Hollis博客里的图片。

2.1 如何理解JVM内存结构?

JVM内存结构是JVM定义的一个规范,描述Java程序运行时,JVM 管理的不同的数据区域;

主要可以分为两类: 线程独享型/线程共享性

线程独享型:The PC Register、JVM Stack、Native Method Stack

线程共享性: JVM Heap、Method Area(Run-Time Constant Pool)

Java内存模型

2.2 JVM 各数据区域作用是什么?

va内存模型

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

存储JVM 加载的类信息、常量、静态变量。线程共享区域,默认为16M, 最大值为64M, 可以通过 -XX:PermSize 和 -XX:MaxPermSize 参数限制方法区大小;

运行时常量池:在类的加载阶段,将class文件常量池中内容存放到运行时常量池(还保持这符号引用)中。经过链接过程的resolve阶段后, 把符号引用替换为直接应用;

关于符号引用和直接引用参考文档: https://juejin.im/post/6844903785416884231

2.2.2 虚拟机栈

方法执行时,都会创建一个栈帧,用于存储局部变量表、操作栈、方法出口等信息,每个方法执行完的过程,就对应着一个战阵在虚拟机栈中从入栈到出栈的过程。

生命周期与线程相同,是线程私有的。

2.2.3. 本地方法栈

JVM栈执行的Java 方法, 而本地方法栈执行的是Native方法。

2.2.4 堆(JAVA堆,GC堆)

堆内存

综述

是有JVM 管理的内存中最大的一个区域, JVM启动时创建,存放实例及数组。

默认大小为物理内存的 1/64, 最大为物理内存的 1/4, 可以通过 -Xms 和 -Xmx 参数进行控制。如: -Xms500m;

默认Idle < 40%, 将使用 Xmx; 当Idle > 70%, 将使用 Xms, 为了避免运行时,频繁调整,我们通常将 Xms与Xmx设置为相同数值;

细节
JDK默认堆空间分配比例JDK默认堆空间分配比例

现代垃圾回收器都是采用分代回收算法,堆被划分为 新生代(Young Generation)和老年代(Old Generation);

新生代:新生代主要是存放新创建的对象, 可以通过 -Xmn控制新生代大小,新生代又分为 Eden Space 和 Survivor Space,SUN JVM 一般将比例设置为 8比1, 也可以通过-XX:SurvivorRation来调整Survivor和Eden大小;

Eden Span 存放新生对象; Survivor Space存放每次Minor GC后存活的对象

老年代:用来存放应用生命周期长的存活对象(新生代多次GC依然存活的对象),如缓存对象;但是不是所有的新创建的对象都会在新生代中,大对象和大数组都会直接进入老年代; 年老代 = Xmx -Xmn

2.2.5 程序计数器

是JVM里 记录当前线程所执行的字节码的行号指示器。在JVM的模型里,字节码解释器工作时,是通过改变计数器来选取下一条需要执行的字节码命令的,分支、循环、异常处理、线程恢复都依赖计数器完成。

3 直接内存

直接内存并不是Java虚拟机内存的一部分,也不是Java虚拟机规范中定义的内存区域。JDK4中新加入NIO,引入了通道与缓冲区的IO方式,它可以调用Native方法直接分配对外内存,这个对外内存就是本机内存,不会影响到对内存的大小。

4 如何设置JVM各数据区域大小 ?

可以用 JConsole 查看程序运行时,Java中堆内存的大小,来调整各参数。

5 PS:遗留难点问题:

快问快答,简要描述。

5.1 常量池

5.1.1 什么是常量?

被final修饰得成员变量, 静态变量,实例变量,局部变量;

5.1.2 什么是常量池?

Class中除了有类版本,字段、方法等描述信息外,还有一项信息就是常量池,用来存放编译器编译器生成各种字面量和符号引用;

5.1.3 什么是方法区运行时常量池?

常量池中得内容,在类加载后,进入方法区。

5.1.4 常量池得好处?

实现对象得共享,避免频繁创建和销毁对象

5.2 什么时字面量和符号引用变量?

final int i = 1;(字面量) 符号应用: 类和接口的全限定名java.lang.Object;字段的名称和描述符I;方法的名称和描述符()V

可以参考: http://47.103.216.138/archives/2517

s 、yushuai_w 都会进入类常量池, s 就是符号引用, yushuai 就是字面量
String s = "yushuai_w";

参考文档

Java内存模型

直接应用与符号引用

Java常量池(类文件常量池、运行时常量池、全局字符串常量池

Java Class文件的结构

JVM老年代和新生代的比例

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值