java---堆、栈、常量池的存储数据
说到Java中堆、栈和常量池,首先还是看看他们各自存放的数据类型吧!
栈:
Java的JVM的内存可分为3个区:堆(heap)、栈(stack)和方法区(method)也叫静态存储区。
堆区:(存放所有new出来的对象;)
1.存储的全部是对象,每个对象都包含一个与之对应的class的信息。(class的目的是得到操作指令)
2.jvm只有一个堆区(heap)被所有线程共享,堆中不存放基本类型和对象引用,只存放对象本身
栈区:(存放基本类型的变量数据和对象的应用,对象(new出来的对象)本身并不存在栈中,而是存放在堆中或者常量池中(字符串常量对象存放在常量池中))
1.每个线程包含一个栈区,栈中只保存基础数据类型的对象(比如int i=1中1就是基础类型的对象)和自定义对象的引用(不是对象)而真实对象都存放在堆区中
2.每个栈中的数据(原始类型和对象引用)都是私有的,其他栈不能访问。
3.栈分为3个部分:基本类型变量区、执行环境上下文、操作指令区(存放操作指令)。
常量池:存放基本类型常量和字符串常量。
方法区:
1.又叫静态区,跟堆一样,被所有的线程共享。方法区包含所有的class和static变量。
2.方法区中包含的都是在整个程序中永远唯一的元素,如class,static变量名,不是常量(它在堆栈中)。
(指数据共享时)对于栈和常量池中的数据可以共享(具有多个引用对象),对于堆中的对象不可以共享(一个引用对象)。 (指线程共享时)比如:同一个进程的多个线程堆栈共享状况哪个描述正确?线程共享堆,但是每个线程有自己的寄存器和栈
解析: 线程占有的都是不共享的,其中包括:栈、寄存器、状态、程序计数器
线程间共享的有:堆,全局变量,静态变量,主要指共享进程的资源;
进程占有的资源有:地址空间,全局变量,打开的文件,子进程,信号量、账户信息。
栈中的数据大小和生命周期是可以确定的,当没有引用指向数据时,这个数据就会自动消失。堆中的对象的由垃圾回收器负责回收,因此大小和生命周期不需要确定,具有很大的灵活性。
而对于字符串来说,其对象的引用都是存储在栈中的,如果是编译期已经创建好(即指用双引号定义的)的就存储在常量池中,如果是运行期(new出来的对象)则存储在堆中。对于equals相等的字符串,在常量池中是只有一份的,在堆中则有多份。
方法区的大小不必是固定的,jvm可以根据应用的需要动态调整。同样方法区也不必是连续的。方法区可以在堆(甚至是虚拟机自己的堆)中分配。jvm可以允许用户和程序指定方法区的初始大小,最小和最大尺寸。
方法区同样存在垃圾收集,因为通过用户定义的类加载器可以动态扩展Java程序,一些类也会成为垃圾。jvm可以回收一个未被引用的(没有实例对象)类所占的空间,以使方法区的空间最小。
要处理好动态派发,一种可能的实现方式是专门开辟一个区,单独管理所有方法,可以按照稳定性对于该对象的所有方法(当然包括父类方法)进行稳定性排序,使相同方法聚集在一起。当方法调用时在方法区搜索的时候一次定位到相同方法的位置的起始处,不管第一个命中方法是父类还是子类,也不管此处相同方法的个数,始终执行第一个。
作者:寻寒
链接:https://www.zhihu.com/question/23599282/answer/25076568
来源:知乎
著作权归作者所有,转载请联系作者获得授权。
举个例子吧!
Java代码
String s1 = "china";
String s2 = "china";
String s3 = "china";
String ss1 = new String("china");
String ss2 = new String("china");
String ss3 = new String("china");
如以下代码:
Java代码
int i1 = 9;
int i2 = 9;
int i3 = 9;
public static final int INT1 = 9;
public static final int INT2 = 9;
public static final int INT3 = 9;
对于成员变量和局部变量:成员变量就是方法外部,类的内部定义的变量;局部变量就是方法或语句块内部定义的变量。局部变量必须初始化。
形式参数是局部变量,局部变量的数据存在于栈内存中。栈内存中的局部变量随着方法的消失而消失。
成员变量存储在堆中的对象里面,由垃圾回收器负责回收。
如以下代码:
Java代码
class BirthDate {
private int day;
private int month;
private int year;
public BirthDate(int d, int m, int y) {
day = d;
month = m;
year = y;
}
省略get,set方法………
}
public class Test{
public static void main(String args[]){
int date = 9;
Test test = new Test();
test.change(date);
BirthDate d1= new BirthDate(7,7,1970);
}
public void change1(int i){
i = 1234;
}
对于以上这段代码,date为局部变量,i,d,m,y都是形参为局部变量,day,month,year为成员变量。下面分析一下代码执行时候的变化:
1. main方法开始执行:int date = 9;
date局部变量,基础类型,引用和值都存在栈中。
2. Test test = new Test();
test为对象引用,存在栈中,对象(new Test())存在堆中。
3. test.change(date);
i为局部变量,引用和值存在栈中。当方法change执行完成后,i就会从栈中消失。
4. BirthDate d1= new BirthDate(7,7,1970);
d1为对象引用,存在栈中,对象(new BirthDate())存在堆中,其中d,m,y为局部变量存储在栈中,且它们的类型为基础类型,因此它们的数据也存储在栈中。 day,month,year为成员变量,它们存储在堆中(new BirthDate()里面)。当BirthDate构造方法执行完之后,d,m,y将从栈中消失。
5.main方法执行完之后,date变量,test,d1引用将从栈中消失,new Test(),new BirthDate()将等待垃圾回收。
java---堆、栈、常量池的存储数据的更多相关文章
- Java堆/栈/常量池以及String的详细详解(转)------经典易懂系统
一:在JAVA中,有六个不同的地方可以存储数据: 1. 寄存器(register). 这是最快的存储区,因为它位于不同于其他存储区的地方——处理器内部.但是寄存器的数量极其有限,所以寄存器由编译器根据 ...
- java 堆 栈 常量池
java 堆中保存new 出来的对象(每个对象都包含一个与之对应的class的信息,[class信息存放在方法区]),堆中分配的内存,有虚拟机的自动垃圾回收器管理,栈内存只对其所属线程可见. java ...
- java内存管理--栈、堆和常量池
今天有朋友问java中String[] str = s.split(",")的内存分析,于是开始查资料并测试.首先,发现在java的内存管理中"常量池"是个很奇 ...
- 第46节:Java当中的常量池
Java当中的常量池 在Java虚拟机jvm中,内存分布为:虚拟机堆,程序计数器,本地方法栈,虚拟机栈,方法区. 程序计数器是jvm执行程序的流水线,是用来存放一些指令的,本地方法栈是jvm操作系统方 ...
- 【Java_基础】java中的常量池
1.java常量池的介绍 java中的常量池,通常指的是运行时常量池,它是方法区的一部分,一个jvm实例只有一个运行常量池,各线程间共享该运行常量池. java常量池简介:java常量池中保存了一份在 ...
- Java中的常量池
JVM中有: Class文件常量池.运行时常量池.全局字符串常量池.基本类型包装类对象 常量池 Class文件常量池: class文件是一组以字节为单位的二进制数据流,在java代码的编译期间,编写的 ...
- 讲一讲Java的字符串常量池,看完你的思路就清晰了
前言 很多朋友Java的字符串常量池的概念困扰了很长一段时间,最近研究了一下jvm指令码,终于对它有了大概的了解. 在展示案例前,我们需要先搞清楚一个概念,众所周知,jvm的内存模型由程序计数器.虚拟 ...
- 19、java内存分配 常量池详解
在class文件中,“常量池”是最复杂也最值得关注的内容. Java是一种动态连接的语言,常量池的作用非常重要,常量池中除了包含代码中所定义的各种基本类型(如int.long等等)和对象型(如Stri ...
- Java字面常量与常量池
Java中的字面常量(区别于final创建的有名常量)通常会保存在常量池中,常量池可以理解为像堆一样的内存区域.但是常量池有一个特性就是,如果常量池中已存在该常量将不会再次为该常量开辟内存 还是看个程 ...
随机推荐
- MySQL定位锁争用比较严重的表
1:查看当前的事务 mysql> SELECT * FROM information_schema.innodb_trx \G 2:查看当前锁定的事务 mysql> SELECT * FR ...
- webp转jpg
webp转jpg CreateTime--2017年12月8日09:32:38 Author:Marydon 1.webp格式介绍 WebP 的优势体现在它具有更优的图像数据压缩算法,能带来更小的 ...
- Android 应用开发实例之情景模式
2013-07-01 Android 应用开发实例 1. 情景模式 使用TabHost来实现主界面的布局. 设置一组RadioButton来切换不同的情景模式. 对比普通情景模式,定时情景模式需要加上 ...
- 多语言 SEO
https://productforums.google.com/forum/?hl=zh-CN#!topic/webmaster-zh-cn/I0MMsm737pc
- FFmpeg音视频同步示例
原文地址:https://my.oschina.net/u/555002/blog/79324 前面整个的一段时间,我们有了一个几乎无用的电影播放器.当然,它能播放视频,也能播放音频,但是它还不能被称 ...
- 调整弹出对话框在ASP.NET应用程序的大小
调整弹出对话框在ASP.NET应用程序的大小 #region 调整弹出对话框在ASP.NET应用程序的大小 protected void PopupWindowControl_Customize ...
- 深入理解MapReduce的架构及原理
1. MapReduce 定义 Hadoop 中的 MapReduce是一个使用简单的软件框架.基于它写出来的应用程序能够执行在由上千个商用机器组成的大型集群上,并以一种可靠容错式并行处理TB级别的数 ...
- WEP无线网络密码破解
一,五分钟实现无线WEP入侵的特点: 众所周知WEP加密入侵需要用户通过监听等方法接收到足够数量的WEP验证数据包,然后通过分析软件使用暴力破解的方法穷举法还原出WEP加密密钥的明文信息.五分钟实现无 ...
- 常用RGB颜色表
作者:张家珩2005-12-02 20:51分类:默认分类 R G B 值 R G B 值 R G B 值 黑色 0 0 0 #000000 黄色 255 255 0 #FFFF0 ...
- Spring Boot 概念知识
转 http://rapharino.com/coder/Spring-Boot-Induction/ Spring Boot Induction 发表于 2016-10-29 | 分类于 c ...