越不懂的越爱装
大家都同等:IT世界没有难不难,只有是否了解过
挑战目录
什么是内存模型
内存模型是为了解释在程序运行时的内存数据结构的构成情况。java中每个java程序都会开启一个进程。同时会对应一个java虚拟机。下面就是一个java虚拟机的数据区域的基础构成。
基础的java虚拟机数据区构成
其中蓝色区域是线程共享的,红色区域时线程独有的(随着线程的创建而创建,销毁而销毁),下面是当虚拟机中有多个线程时的数据区构成。每个大的红框表示一个线程独有的数据区域。
多线程时的java虚拟机数据区构成
上面每个都是什么?
-
方法区:
方法区
- Class文件结构:是所有线程的共享区域,存储class类文件加载后的类模板数据(不是new出来的实例.而是相当于类模板数据)。
可以使用十六进制文本工具查看.class文件,其中的的顺序分别代表如下:
类型 | 名称 | 数量 | 功能 |
---|---|---|---|
4个字节的无符号数 | maginc | 1=0xCAFEBABE | 魔术:确定这个文件是否为一个<br />能被虚拟机接受的Class文件 |
2个字节的无符号数 | MinorVersion | 1= | 次版本号:和JDK的版本相关联 |
2个字节的无符号数 | MajorVersion | 1= | 主版本号:和JDK的版本相关联 |
2个字节的无符号数 | constant_pool_count | 1=0号位常量+真实常量数 | 常量池入口:代表常量池中常量的总个数<br />第0个常量被留出来做特殊考虑,所以<br />常量池的计数是从1开始的 |
cp表格 | constant_pool | 常量池入口数-1 | 常量池表格:存放常量地址1<br />每个常量的耗费空间和存储的类型有关 |
2个字节的无符号数 | access_flags | 1= | |
2个字节的无符号数 | this_class | 1= | |
2个字节的无符号数 | super_class | 1= | |
2个字节的无符号数 | interfaces_count | 1= | |
2个字节的无符号数 | interfaces | interfaces_count个 | |
2个字节的无符号数 | fields_count | 1= | |
fields_info | fields | fields_count个 | |
2个字节的无符号数 | methods_count | 1 | |
method_info | methods | methods_count个 | |
2个字节的无符号数 | attributes_count | 1= | |
attributes_info | attributes | attributes_count个 |
- 运行时常量池(存储编译时期生成的字面量、符号引用和直接引用)
字面量: 类中的静态变量,字符串。但是java8 将 静态变量 、StringTable 都从方法区移动到 堆中,主 要是想进行GC。方法区也能GC,但只能full GC,频率会很低。
符号引用:
直接引用:
-
堆
是所有线程的共享区域,存储class的实例对象。
java堆- Eden区:
- Survivor区:
- Old区:
堆内存的大小:虚拟分配大小,并不会把这么大的内存空间锁定占据了(不会出现启动多个空的jar把内存耗光)
- 堆内存分配:
- 由-Xms指定,默认物理内存的1/64。最大内存由-Xmx指定,默认物理内存的1/4。
- 空余堆内存小于40%时,会增大直到-Xmx的最大限制;空余堆内存大于70%时,会减少堆直到-Xms的最小限制
- 服务器一般设置-Xms、-Xmx相等以避免在每次GC后调整堆的大小
- 非堆内存分配
- 由-XX:PermSize设置内存初始值,默认是物理内存的1/64;
- 由XX:MaxPermSize设置最大非堆内存的大小,默认是物理内存的1/4
3.JVM最大内存
- 限制于实际的最大物理内存
- 限制于操作系统位数:64位无限制,32位限制一般是2GB-3GB(一般来说Windows系统下为1.5G-2G,Linux系统下为2G-3G)
-
程序计数器
-
Java虚拟机栈
-
本地方法栈
与Java虚拟机类似,不过这个是用来执行native方法时使用的。
网友评论