Java 内存结构

Java内存结构

在这里插入图片描述

1 程序计数器

1.1 作用

当前线程所执行的字节码的行号指示器,字节码解释器工作时就是通过改变程序计数器的值来选取下一条需要执行的字节码指令。

1.2 特点

线程私有(每条线程有一个独立程序计数器)
不会内存溢出

2 Java虚拟机栈

2.1 作用

虚拟机栈描述的是Java方法执行的内存模型:每个方法被执行的时候都同时会创建一个栈帧用于储存局部变量表、操作栈、动态链接、方法出口等信息。每个方法被调用直到完成对应着一个栈帧再虚拟机栈中出栈和入栈。

2.2 特点

线程私有
垃圾回收不涉及栈内存
栈内存分配不是越大越好(太大影响线程数目)

3 本地方法栈

与虚拟机栈类试,区别是虚拟机栈为执行Java方法服务,本地方法栈是为虚拟机使用到的Native方法服务。
Native Method:就是一个java调用非java代码的接口,比如C。

4 Java堆

4.1 定义

此内存区域的唯一目的就是存放对象实例,所有的对象实例以及数组都要在堆上分配。

4.2 特点

它是线程共享的,堆中对象都需要考虑线程安全的问题
有垃圾回收机制

5 方法区

方法区是线程共享的内存区域,用于存储已加载的类信息、常量、静态变量、编译后的代码等。
JDK1.7以前使用永久代实现方法区,1.8及以后使用元空间实现方法区。(元空间并不在虚拟机中,而是使用本地内存)

6 运行时常量池

运行时常量池是方法区的一部分,用于存放编译器生成的各种字面量和符号引用。

7 直接内存

直接内存不是虚拟机运行时的一部分。
常见于 NIO 操作时,用于数据缓冲区,它w可以使用Native直接分配堆外内存。
分配回收成本较高,但读写性能高

附录 StringTable

常量池中的字符串仅是符号,第一次用到时才变为对象
利用串池的机制,来避免重复创建字符串对象
字符串变量拼接的原理是 StringBuilder (1.8)
字符串常量拼接的原理是编译期优化
可以使用 intern 方法,主动将串池中还没有的字符串对象放入串池
1.8 将这个字符串对象尝试放入串池,如果有则并不会放入,如果没有则放入串池, 会把串池中的对象返回
1.6 将这个字符串对象尝试放入串池,如果有则并不会放入,如果没有会把此对象复制一份,放入串池, 会把串池中的对象返回

下面通过一段代码演示

String s1 = "a";
String s2 = "b";
String s3 = "a" + "b";
String s4 = s1 + s2;
//该语句调用 new StringBuider().append("a").append("b").toString(); 
//在toString中new了新的字符串对象,故s4在堆中
String s5 = "ab";
String s6 = s4.intern();

System.out.println(s3 == s4);//false
System.out.println(s3 == s5);//true
System.out.println(s3 == s6);//true

String x2 = new String("c") + new String("d");
String x1 = "cd";
x2.intern();
// 问,如果调换了【最后两行代码】的位置呢,如果是jdk1.6呢
System.out.println(x1 == x2);//false
//若调换后两行代码,则会将x2放入串池,则x1==x2,代码如下

String x2 = new String("c") + new String("d");
x2.intern();
String x1 = "cd";
System.out.println(x1 == x2);//true

//若是jdk1.6则不会将x2放入串池故x1!=x2
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值