java你可能不知道的事(2)--堆和栈
在java语言的学习和使用当中你可能已经了解或者知道堆和栈,但是你可能没有完全的理解它们。今天我们就一起来学习堆、栈的特点以及它们的区别。认识了这个之后,你可能对java有更深的理解。
Java堆内存(Heap Memory)
堆内存在Java运行时主要去回收对象和JRE的类。当我们创建了一个对象(也就是 new一个对象),在堆内存就会为对象分配一个空间,Java垃圾回收器(GC)运行在堆内存里,一旦发现没有任何地方引用到这个对象,就释放这个对象所占的内存。
被创建的对象存在于堆内存,并且拥有全局权限,能被应用的任何地方引用到。
Java栈内存(Stack Memory)
堆内存是单线程执行的,它的空间比堆内存空间要小。它里面会包括定义在方法里的、短时间存在的局部变量,这些局部变量总是引用到堆内存的对象。堆内存还有个特点就是后进先出。当一个方法被调用之后,在栈内存就会为这个方法产生一个内存区域来保存方法里的基本数据类型数据和引用了堆内存中对象的局部变量。当这个方法执行完毕,这个块没有用了,就会被垃圾回收器回收,接着继续下一个方法。
加深理解
先来看一段简单的代码
public class TestMemory { public static void main(String[] args) {
int i = 666;//line1
Object object = new Object();//line2
TestMemory testMemory = new TestMemory();//line3
testMemory.test(object);//line4
}
//line5
private void test(Object params){//line6
String str = params.toString();//line7
System.out.println(str);//line8
}
}
//line9
下面这张图片展示了上面代码的内存信息。
1、当程序运行时,JVM会先加载运行时的类和我们自己写的类信息,这些类信息加载后存在堆内存当中。
2、接着进入到main方法,第一行line1创建了一个基本数据类型i=666,所以创建了一个main方法的内存块,它里面同时存放了i=666;
3、接着line2和line3的位置
Object object = new Object();
TestMemory testMemory = new TestMemory();创建了两个局部变量,object和testMemory,同时在堆里存放了两个新的对象Object和TestMemory。(每次我们new 一个对象都会在堆区产生一块内存区给它分配空间)。同时object和testMemory引用了new出来的对象。
4、现在到了line4,test方法了,当调用到test方法的时候,在栈的顶层创建了一块test()方法的内存区(我们说过栈的特点就是后进先出),由于在 Java里的传递是值传递,所以就有了参数object产生了一个新的引用。
5、最后调用了toString产生了一个字符串常量存放在了String pool里,并且str 引用了它。(如果你有String类感兴趣,你可能喜欢 》Java你可能不知道的事系列1_String类
6、当test方法结束,它里面的变量也就被GC回收掉了。接着main方法也就结束。Java在运行时释放这些内存并结束程序的运行。
总结
1、当一个对象被创建,总是会在堆内存为它分配空间并且存储,如果有赋值就会将变量引用到对象。而栈内存就是存放这些引用对象的局部变量。
2、栈内存的生命周期很短,而堆内存从程序执行开始到结束一只都需要工作。因为栈内存没当执行完一个方法,它们所占的内存区就会被释放。而堆内存里的对象只有在没有任何变量引用到它的时候才可能会被释放。
3、栈内存大小相比于堆内存非常小。但是它相对于堆内存又比较快。
java你可能不知道的事(2)--堆和栈的更多相关文章
- java你可能不知道的事(2)--堆和栈<转>
在java语言的学习和使用当中你可能已经了解或者知道堆和栈,但是你可能没有完全的理解它们.今天我们就一起来学习堆.栈的特点以及它们的区别.认识了这个之后,你可能对java有更深的理解. Java堆内存 ...
- Java你可能不知道的事(3)HashMap
概述 HashMap对于做Java的小伙伴来说太熟悉了.估计你们每天都在使用它.它为什么叫做HashMap?它的内部是怎么实现的呢?为什么我们使用的时候很多情况都是用String作为它的key呢?带着 ...
- Java你可能不知道的事系列(1)
概述 本类文章会不段更新分析学习到的经典面试题目,在此记录下来便于自己理解.如果有不对的地方还请各位观众拍砖. 今天主要分享一下常用的字符串的几个题目,相信学习java的小伙伴们对String类是再熟 ...
- Java你可能不知道的事系列1
概述 本类文章会不段更新分析学习到的经典面试题目,在此记录下来便于自己理解.如果有不对的地方还请各位观众拍砖. 今天主要分享一下常用的字符串的几个题目,相信学习java的小伙伴们对String类是再熟 ...
- Spring中你可能不知道的事(一)
Spring作为Java的王牌开源项目,相信大家都用过,但是可能大家仅仅用到了Spring最常用的功能,Spring实在是庞大了,很多功能可能一辈子都不会用到,今天我就罗列下Spring中你可能不知道 ...
- ES6 你可能不知道的事 – 基础篇
序 ES6,或许应该叫 ES2015(2015 年 6 月正式发布),对于大多数前端同学都不陌生. 首先这篇文章不是工具书,不会去过多谈概念,而是想聊聊关于每个特性 你可能不知道的事,希望能为各位同学 ...
- overflow:hidden 你所不知道的事
overflow:hidden 你所不知道的事 overflow:hidden这个CSS样式是大家常用到的CSS样式,但是大多数人对这个样式的理解仅仅局限于隐藏溢出,而对于清除浮动这个含义不是很了解. ...
- “吃人”的那些Java名词:对象、引用、堆、栈
记得中学的课本上,有一篇名为<狂人日记>课文:那时候根本理解不了鲁迅写这篇文章要表达的中心思想,只觉得满篇的“吃人”令人心情压抑:老师在讲台上慷慨激昂的讲,大多数的同学同我一样,在课本面前 ...
- 【转】Java运行时数据区简介及堆与栈的区别
理解JVM运行时的数据区是Java编程中的进阶部分.我们在开发中都遇到过一个很头疼的问题就是OutOfMemoryError(内存溢出错误),但是如果我们了解JVM的内部实现和其运行时的数据区的工作机 ...
随机推荐
- UWP开发入门(二十三)——WebView
本篇讨论在UWP开发中使用WebView控件时常见的问题,以及一些小技巧. WebView是实际开发中常用的控件,很多大家抱怨的套网页的应用都是通过WebView来实现的.这里要澄清一个问题,套网页的 ...
- Load Audio or Vedio files
//Load Audio or Vedio files private void btnLoadFile_Click(object sender, EventArgs e) { Startindex ...
- node.js下LDAP查询实践
目标: 从一个LDAP Server获取uid=kxh的用户数据 LDAP地址为:ldap://10.233.21.116:389 在工程根目录中,先npm一个LDAP的访问库ldpajs npm i ...
- Rebalance Customer Balances Utility的使用
用户不管是打开A/R Posted Transactions Detail还是A/R Posted Transactions Summary 窗口,均显示如下一个警示: 打开Currency Code ...
- 在Linux(Ubuntu)下搭建ASP.NET Core环境并运行 继续跨平台
最新教程:http://www.cnblogs.com/linezero/p/aspnetcoreubuntu.html 无需安装mono,在Linux(Ubuntu)下搭建ASP.NET Core环 ...
- TreeView使用
1.添加节点,实现拖拽功能 private void Form1_Load(object sender, EventArgs e) { TreeNode node1 = new TreeNode(); ...
- 速战速决 (1) - PHP: 概述, 常量, 变量, 运算符, 表达式, 控制语句
[源码下载] 速战速决 (1) - PHP: 概述, 常量, 变量, 运算符, 表达式, 控制语句 作者:webabcd 介绍速战速决 之 PHP 概述 常量 变量 运算符 表达式 控制语句 示例1. ...
- 背水一战 Windows 10 (8) - 控件 UI: StateTrigger
[源码下载] 背水一战 Windows 10 (8) - 控件 UI: StateTrigger 作者:webabcd 介绍背水一战 Windows 10 之 控件 UI VisualState 之 ...
- python 局部变量和全局变量 global
当你在函数定义内声明变量的时候,它们与函数外具有相同名称的其他变量没有任何关系,即变量名称对于函数来说是 局部 的.这称为变量的 作用域 .所有变量的作用域是它们被定义的块,从它们的名称被定义的那点开 ...
- PostgreSQL类型转换
1.int装string select CAST (1234 AS text) select to_char(1234,’999‘) 2.string转int select cast('999' as ...