Java的内存--存储
0.参考资料:
http://www.j2megame.org/index.php/content/view/2246/125.html
1.Java的内存机制
Java 把内存划分成两种:一种是栈内存,另一种是堆内存。在函数中定义的一些基本类型的变量和对象的引用变量都是在函数的栈内存中分配,当在一段代码块定义一个变量时,Java 就在栈中为这个变量分配内存空间,当超过变量的作用域后(比如,在函数A中调用函数B,在函数B中定义变量a,变量a的作用域只是函数B,在函数B运行完以后,变量a会自动被销毁。分配给它的内存会被回收),Java 会自动释放掉为该变量分配的内存空间,该内存空间可以立即被另作它用。
堆内存用来存放由 new 创建的对象和数组,在堆中分配的内存,由 Java 虚拟机的自动垃圾回收器来管理。在堆中产生了一个数组或者对象之后,还可以在栈中定义一个特殊的变量,让栈中的这个变量的取值等于数组或对象在堆内存中的首地址,栈中的这个变量就成了数组或对象的引用变量,以后就可以在程序中使用栈中的引用变量来访问堆中的数组或者对象,引用变量就相当于是为数组或者对象起的一个名称。引用变量是普通的变量,定义时在栈中分配,引用变量在程序运行到其作用域之外后被释放。而数组和对象本身在堆中分配,即使程序运行到使用 new 产生数组或者对象的语句所在的代码块之外,数组和对象本身占据的内存不会被释放,数组和对象在没有引用变量指向它的时候,才变为垃圾,不能在被使用,但仍然占据内存空间不放,在随后的一个不确定的时间被垃圾回收器收走(释放掉)。这也是 Java 比较占内存的原因,实际上,栈中的变量指向堆内存中的变量,这就是 Java 中的指针!
代码实例Test01:单个对象创建

class Person{
String name;
int age;
public void tell(){
System.out.println("姓名:"+name+"年龄"+age);
}
} public class Test01 {
public static void main(String[] args) {
Person per=new Person();
}
}

在上述程序中实例化了一个对象per,在实例化对象的过程中需要在内存中开辟空间,这其中就包括栈内存和对内存。具体的内存分配如下图所示:
我们可以从上图中发现,对象名称per被保存在了栈内存中(更加准确的说法是,在栈内存中保存的是堆内存空间的访问地址),而对象的具体内容,比如属性name和age,被保存在了堆内存中。因为per对象只是被实例化,还没有具体被赋值,所以都是默认值。字符串的默认值为null,int类型的默认值为0。前面也已经提到,堆内存空间必须使用new关键字才能开辟。
代码实例Test02:多个对象创建

class Person{
String name;
int age;
public void tell(){
System.out.println("姓名:"+name+",年龄:"+age);
}
} public class Test02 {
public static void main(String[] args) {
Person per1=new Person();
Person per2=new Person(); per1.name="张三";
per1.age=30;
per2.name="李四";
per2.age=33; per1.tell();
per2.tell();
}
}

关键概念:类跟数组一样,都是属于引用类型,引用类型就是指一堆对内存可以同时被多个栈内存指向。下面来看一下引用传递的简单实例。
代码实例Test03:对象引用传递1

class Person{
String name;
int age;
public void tell(){
System.out.println("姓名:"+name+",年龄:"+age);
}
} public class Test03{
public static void main(String[] args) {
Person per1=new Person();
Person per2=per1; per1.name="张三";
per1.age=30;
per2.age=33; per1.tell();
per2.tell();
}
}

程序运行结果为:
姓名:张三,年龄:33
姓名:张三,年龄:33
从程序的运行结果可以发现,两个对象输出的内容一样,实际上所谓的引用传递,就是将一个堆内存空间的使用权交个多个栈内存空间,每个栈内存空间都可以修改堆内存空间的内容,此程序的内存分配图如下所示:
注意:上述实例中对象per2没有堆内存空间,这是因为对象per2只进行了声明操作,也没有进行实例化操作。只有使用new关键字实例化以后才会有对内存空间。
代码实例Test04:对象引用传递2

class Person{
String name;
int age;
public void tell(){
System.out.println("姓名:"+name+",年龄:"+age);
}
} public class Test04 {
public static void main(String[] args) {
Person per1=new Person();
Person per2=new Person(); per1.name="张三";
per1.age=30;
per2.name="李四";
per2.age=33;
per2=per1; per1.tell();
per2.tell();
}
}

上述程序运行结果为:
姓名:张三,年龄:30
姓名:张三,年龄:30
从程序的输出结果可以发现可Test03一样。不过内存分配发生了一些变化,具体如下所示:
注意点:
- Java本身提供垃圾收集机制(Garbage Collection,GC),会不定期施放不用的内存空间,只要对象不用了,就会等待GC释放空间,如上面堆内存中的name="李四";age=33。
- 一个栈内存只能指向一个对内存空间,如果要想再指向其他的堆内存空间,则必须先断开已有的指向才能分配新的指向。
java中常用的内存区域
在java中主要存在4块内存空间,这些内存的名称及作用如下:
- 栈内存空间:保存所有的对象名称(更准确地说是保存了引用的堆内存空间的地址)
- 堆内存空间:保存每个对象的具体属性内容。
- 全局数据区:保存static类型的属性。
- 全局代码区:保存所有的方法定义。
Java的内存--存储的更多相关文章
- Java的内存--存储(1)
有次去面试,面试官突然问我这个问题,当时我只知道怎么写最优化,但是具体不知道为什么那样写,身价立马下降哦 1. 以下开发习惯,你怎么看? for(int i=0;i<2;i++){ Person ...
- 小白请教几个关于Java虚拟机内存分配策略的问题
最近在看周志明所著的<深入理解Java虚拟机>,有几个问题不太明白,希望对虚拟机有研究的哥们儿帮我解答一下.先说一下我进行试验的环境: 操作系统:Mac OS X 10.11.6 EI C ...
- java中内存分配策略及堆和栈的比较
Java把内存分成两种,一种叫做栈内存,一种叫做堆内存 在函数中定义的一些基本类型的变量和对象的引用变量都是在函数的栈内存中分配.当在一段代码块中定义一个变量时,java就在栈中为这个变量分配内存空间 ...
- Java堆内存的十个要点
Java中的堆空间是什么? 当Java程序开始运行时,JVM会从操作系统获取一些内存.JVM使用这些内存,这些内存的一部分就是堆内存.堆内存通常在存储地址的底层,向上排列.当一个对象通过new关键字或 ...
- java线程内存模型,线程、工作内存、主内存
转自:http://rainyear.iteye.com/blog/1734311 java线程内存模型 线程.工作内存.主内存三者之间的交互关系图: key edeas 所有线程共享主内存 每个线程 ...
- Java虚拟机内存管理机制
自动内存管理机制 Java虚拟机(JVM)在执行Java程序过程中会把它所管理的内存划分为若干个不同的数据区域.这些区域都有各自的用途,以及创建和销毁的时间,有的区域随着虚拟机进程的启动而存在,有的区 ...
- java堆内存和栈内存的处理
前段时间学习二叉树在处理删除操作的时候遇到一个头疼的问题:删除节点的时候明明已经置null了可树上该节点依旧存在,还必须执行node.father.left = null;才可以删除node节点,寻找 ...
- Java 对象内存分配与回收
JVM内存区域模型: * 程序计数器,内存区域极小,是当前线程的字节码执行行号指示器: * 虚拟机栈.本地方法栈,即平时所说的“栈”,是虚拟机用来执行方法(包括Java.非Java方法)时,使用的临时 ...
- Java虚拟机内存模型及垃圾回收监控调优
Java虚拟机内存模型及垃圾回收监控调优 如果你想理解Java垃圾回收如果工作,那么理解JVM的内存模型就显的非常重要.今天我们就来看看JVM内存的各不同部分及如果监控和实现垃圾回收调优. JVM内存 ...
随机推荐
- H5 中html 页面存为图片并长按 保存
最近接到的一个新需求:页面一个静态H5,中间有一页是输入信息,然后跳转到最后一页,自动将页面生成图片,用户可以长按图片保存到手机上. 展示一下最后一页的样子: 刚拿到这个需求,在网上看了很多文章,最普 ...
- js之正则表达式基础
字符串是编程时涉及到的最多的一种数据结构,对字符串进行操作的需求几乎无处不在.比如判断一个字符串是否是合法的Email地址,虽然可以编程提取@前后的子串,再分别判断是否是单词和域名,但这样做不但麻烦, ...
- javascript实现数据结构: 稀疏矩阵之三元组线性表表示
稀疏矩阵(Sparse Matrix):对于稀疏矩阵,目前还没有一个确切的定义.设矩阵A是一个n*m的矩阵中有s个非零元素,设 δ=s/(n*m),称δ为稀疏因子, 如果某一矩阵的稀疏因子δ满足δ≦ ...
- LotusScript_文档查询循环方法整理
1. 视图(View)查询 ... Set view = db.GetView("ViewName") Set doc = view.GetFirstDocument While ...
- 使用weinre调试Web应用及PhoneGap应用
Web开发者经常使用Firefox的firebug或者Chrome的开发人员工具进行Web调试,包括针对JavaScript,DOM元素和CSS样式的调试.但是,当我们期望为移动Web站点或应用进行调 ...
- Select selectedIndex 属性
定义和用法 selectedIndex 属性可设置或返回下拉列表中被选选项的索引号. 注意: 若允许多重选择,则仅会返回第一个被选选项的索引号. 语法 设置 selectedIndex 属性: sel ...
- Siebel escript学习笔记
Siebel(escript)的学习:1.Siebel的数据类型Primitive(原始的)---Number,Integer,Hexadecimal(十六进制),Octal(八进制),Floatin ...
- Hadoop ->> 关于数据分割(Data Split)的思考
今天开始学习Hadoop这门热门的数据库技术.直接从被奉为Hadoop圣经的<Hadoop The Definitive Guide 4th Edition>入手.第一章作者写到一个关于分 ...
- 【NLP_Stanford课堂】正则表达式
或者 [Ww]oods,方括号里的是或的关系,符合其一即被提出.用来匹配单个字符 [A-Z]:表示所有的大写字母之一 [a-z]:表示所有的小写字母之一 [0-9]:表示所有的0-9的数字之一 否定: ...
- Selenium2学习(十一)-- select下拉框
本篇以百度设置下拉选项框为案例,详细介绍select下拉框相关的操作方法. 一.认识select 1.打开百度-设置-搜索设置界面,如下图所示 2.箭头所指位置,就是select选项框,打开页面 ...