[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程序使用。有待补充~

相关推荐
追随者永远是胜利者2 小时前
(LeetCode-Hot100)49. 字母异位词分组
java·算法·leetcode·职场和发展·go
吴声子夜歌2 小时前
RxJava——Flowable与背压
android·java·rxjava
Thanwind2 小时前
大二上结束随笔
java
keyborad pianist2 小时前
Web开发 Day1
开发语言·前端·css·vue.js·前端框架
坚持就完事了2 小时前
Python的类型注解
开发语言·python
wjs20242 小时前
HTML URL 编码
开发语言
wjs20242 小时前
Lua 循环
开发语言
Evand J3 小时前
matlab GUI制作界面的一些笔记(入门)
开发语言·笔记·matlab
我是大猴子3 小时前
Java面经
java·开发语言
Never_Satisfied3 小时前
在c#中,如何删除字符串中的第x个字符
开发语言·c#