[Java基础]——JVM内存模型

目录

程序计数器:

本地方法栈:

虚拟机栈:

灵魂四问❓

方法区:

区分串池和常量池

intern()方法应用实例

堆:

直接内存(操作系统中的):


程序计数器:

程序计数器会保存下一条指令的地址!!!

如果是64位操作系统,也就是有64根地址线,那么地址对应的大小就是8个字节

本地方法栈:

存储一些用C++语言编写的 native方法

虚拟机栈:

函数入栈形成栈帧,函数执行完出栈,销毁栈帧。

每个线程都有自己的方法栈。

栈中的数据不会被垃圾回收

灵魂四问❓

栈帧包括什么:

局部变量表 - 保存this和变量的。注意局部变量是可以复用内存槽的,int占1个槽位 long占2个槽位

栈内存会被JVM回收嘛:

不会,方法调用完出栈

栈内存分配的越大越好吗:

不是,因为栈内存大了,线程数就少了,并发少了,只是你单线程能调用的方法多了一点,并不让你运行速度变快,反而会慢。

方法内的局部变量是线程安全的吗?

是的,因为每一个线程的栈帧是私有的,不会共享那个变量,如果变量加了static那就要考虑线程安全问题了。还有就是变量在参数或者返回值也都面临线程安全问题。

方法区:

1.8及以前:逻辑上是堆的一部分,它是所有线程共享的一块内存区域,他存储了类的成员变量、构造方法、类的结构、运行时常量池等。

1.8以后:从堆改为元空间,用的是操作系统的内存,但是这个运行时常量池还是在堆中。

区分串池和常量池

**常量池:**存放Class类的信息

**串池:**也叫运行时常量池,程序运行时,会将程序中第一次用到的常量存放到串池中,串池中维护的是一个HashTable,key就是字符串的地址,值就是字符串的内容。

故:

我们new出来的对象是在堆上的,地址不同,所以

String s1 = "ab";

String s2 = new String("ab");

s1 != s2;

像"a" + "b"这种在编译时编译器就优化了,从串池中找有无"ab"。

下面的代码很重要

java 复制代码
        String s = new String("a") + new String("b");
        System.out.println(s.hashCode());
        String s2 = s.intern(); // 有返回串池中的对象,没有将s的引用放进去
        System.out.println(s.hashCode());
        String x = "ab";
        System.out.println(x.hashCode());
        System.out.println(s2.hashCode());
intern()方法应用实例

**场景还原:**流传推特要存储用户名和用户地址,但是这需要30个G的内存空间,并且呢,这些用户许多地址都是重复的,那么使用了intern之后,内存直接从30G变成了几百MB。

intern原理:

将字符串放到Stringtable中,Stringtable是内存中维护的一个Hashtable,也就是那个运行时常量池,它是由数组+链表/红黑树构成的,不允许重复,存储时根据hashcode算出的地址值,存到相应的位置。

intern方法:

如果StringTable中存在该字符串,直接返回字该字符串的引用,如果不存在,将该字符串的引用放入到StringTable中。

堆:

new 出来的对象就是在堆中存储的

堆中的对象会被JVM垃圾回收器回收。

直接内存(操作系统中的):

如果Java要使用操作系统中的内存,需要创建两处缓存,一处是系统缓存区,一处是Java缓存区,这样就影响性能,如果使用bytebuffer中的某些方法创建的缓存,可以直接被我们Java程序使用。有待补充~

相关推荐
运维行者_几秒前
网络监控工具怎么选?从设备监控到智能运维的能力清单
运维·服务器·开发语言·网络·人工智能·支持向量机·php
用户3126874877208 分钟前
Java 对象内存布局:压缩指针、对齐填充与 JOL 实测
java
东华果汁哥24 分钟前
【Spring AI 实战】从零开始调用大模型接口,构建 Java AI 应用
java·人工智能·spring
“AI国潮设计-小江”1 小时前
【AIGC实战】Python+SDXL打造“潮汕英歌舞IP”万能立牌插件,批量生成“发财元宝蛋糕”视觉营销方案(附源码)
开发语言·人工智能·python·prompt·aigc
Song_RsHt1 小时前
Redis 与微服务,什么场景下无可替代
java·redis·后端·学习·微服务
学长毕设1 小时前
基于SpringBoot的建筑材料管理系统-附源码
java·spring boot·后端
lhbweilai1 小时前
分析FreeRTOS内核对象API的源码实现(八)
c语言·开发语言·stm32·单片机
努力努力再努力wz1 小时前
【C++高阶系列】C++20 协程底层原理:函数为什么能暂停?从状态机到 Task,彻底串起挂起、恢复与协程调度
开发语言·c++·c++20·1024程序员节
摸爬滚打的小李2 小时前
关于 Arthas
java·后端
咩咩啃树皮2 小时前
JavaScript 中 this 指向为什么总在变?
开发语言·前端·javascript