A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© Y_Y 中级黑马   /  2013-10-25 19:18  /  1299 人查看  /  8 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

本帖最后由 Y_Y 于 2013-10-26 10:24 编辑

今天在看老师视屏的时候,一直在讲程序中的数据在内存中的存储比如堆内存 栈 方法区等,我就想了  为什么把内存分成几块,而且是怎么实现的?

8 个回复

倒序浏览
程序内存的动态改变部分可以分成两个区:
栈(stack):内存总是向一个方向增加或向相反方向减少,这个内存区用于存放方法或块中声明的局部变量。遇到局部变量声明时(包括调用方法中的变元变量-通C中的形参)内存增长,退出方法或块时这些变量弹出堆栈。
堆(heap):用于存储对象,对象的引用放在堆栈区,但是对象的数据区必须存放在堆中。堆是内存单元构成的一个巨大的表。New语句生成新对象时,保留的小块内存单元随时进行分配,一个内存单元块不再被现有变量引用时,这些不用的单元被释放和收集起来。

堆内存存放的有:String、基本数据类型、对象引用、static静态代码块等
栈内存存放的有:StringBuffer、对象等

所以根据它们的功能和作用的不同,进行分区,不同区存储不同类型的数据。

评分

参与人数 1技术分 +1 收起 理由
杨增坤 + 1

查看全部评分

回复 使用道具 举报
Java把内存分成两种,一种叫做栈内存,一种叫做堆内存

在函数中定义的一些基本类型的变量和对象的引用变量都是在函数的栈内存中分配。当在一段代码块中定义一个变量时,java就在栈中为这个变量分配内存空间,当超过变量的作用域后,java会自动释放掉为该变量分配的内存空间,该内存空间可以立刻被另作他用。

堆内存用于存放由new创建的对象和数组。在堆中分配的内存,由java虚拟机自动垃圾回收器来管理。在堆中产生了一个数组或者对象后,还可以在栈中定义一个特殊的变量,这个变量的取值等于数组或者对象在堆内存中的首地址,在栈中的这个特殊的变量就变成了数组或者对象的引用变量,以后就可以在程序中使用栈内存中的引用变量来访问堆中的数组或者对象,引用变量相当于为数组或者对象起的一个别名,或者代号。

引用变量是普通变量,定义时在栈中分配内存,引用变量在程序运行到作用域外释放。而数组&对象本身在堆中分配,即使程序运行到使用new产生数组和对象的语句所在地代码块之外,数组和对象本身占用的堆内存也不会被释放,数组和对象在没有引用变量指向它的时候,才变成垃圾,不能再被使用,但是仍然占着内存,在随后的一个不确定的时间被垃圾回收器释放掉。这个也是java比较占内存的主要原因,实际上,栈中的变量指向堆内存中的变量,这就是 Java 中的指针!

评分

参与人数 1技术分 +1 收起 理由
杨增坤 + 1

查看全部评分

回复 使用道具 举报
Java的内存分配
  Java程序运行时的内存结构分成:方法区、栈内存、堆内存、本地方法栈几种。
方法区
   存放装载的类数据信息,包括:基本信息:每个类的全限定名、每个类的直接超类的全限定名、该类是类还是接口、该类型的访问修饰符、直接超接口的全限定名的有序列表。每个已装载类的详细信息:运行时常量池、字段信息、方法信息、静态变量、到类classloader的引用、到类class的引用。
  栈内存
    Java栈内存由局部变量区、操作数栈、帧数据区组成,以帧的形式存放本地方法的调用状态(包括方法调用的参数、局部变量、中间结果……)。
  堆内存
    堆内存用来存放由new创建的对象和数组。在堆中分配的内存,由Java虚拟机的自动垃圾回收器来管理。
  本地方法栈内存
    Java通过Java本地接口JNI(Java Native Interface)来调用其它语言编写的程序,在Java里面用native修饰符来描述一个方法是本地方法
另外强调的是:
java中内存主要包含4块,即heap(堆内存)、stack(栈内存)、data segment(静态变量或是常量存放区)、codesegment(方法区).
堆内存中存放的是new出的对象,new出的对象只包含成员变量。
栈内存中:存放的是局部成员变量。对于基本的数据类型存放的是基本变量的值,而对于对象变量,存放的是堆内存的地址。
静态、常量区:存放的是静态变量(类变量)或是常量。
方法区:存放的是对象的方法。因此即使new出多个对象也是只是存在一个方法。
希望对您的理解有帮助。
回复 使用道具 举报 1 0
1.寄存器:最快的存储区,由编译器根据需求分配,我们在程序中无法控制.
2.栈:存放基本类型的变量数据和对象的引用,当对象本身不存放在栈中,而是存放在(new出来的对象)或者常量池中(字符串常量对象存放在常量池中)
3.堆:存放所有new出来的对象.
4.静态域:存放静态成员(static定义的).
5.常量池:存放字符串常量和基本类型常量(public static final)
6.非RAM存储:硬盘永久存储空间
如:String s1="abc";
      String s2="abc";
      这里的abc是存放在常量池中的,s1,s2是指向同一个abc,即s1,s2共享同一个abc.
      String s3=new String("abc");
      这里的abc是存放在堆中的,是新创建出来的对象,也就是说可以创建多个内容相同的对象
      String s4=new String("abc");  
      s4,s3是两个对象他们指向的是在堆中处在不同地址的abc

评分

参与人数 1技术分 +1 收起 理由
乔兵 + 1

查看全部评分

回复 使用道具 举报
◆寄存器:我们在程序中无法控制  ◆栈:存放基本类型的数据和对象的引用,但对象本身不存放在栈中,而是存放在堆中  ◆堆:存放用new产生的数据  ◆静态域:存放在对象中用static定义的静态成员  ◆常量池:存放常量  ◆非RAM存储:硬盘等永久存储空间  
回复 使用道具 举报
小夕 初级黑马 2013-10-26 07:47:24
7#
◆寄存器:我们在程序中无法控制  ◆栈:存放基本类型的数据和对象的引用,但对象本身不存放在栈中,而是存放在堆中  ◆堆:存放用new产生的数据  ◆静态域:存放在对象中用static定义的静态成员  ◆常量池:存放常量  ◆非RAM存储:硬盘等永久存储空间  
回复 使用道具 举报
麦子 中级黑马 2013-10-26 08:56:03
8#
大白话解释:
    不同数据的数据权限,生命周期一类的属性不一样,由于虚拟机在内存中分配的空间是有限的,那么就要有一套行之有效的垃圾回收机制。而垃圾回收机制不可能在某个时刻将虚拟机所开辟的内存空间全部回收,它要根据不同区域采取不同的措施,就像对内存中的实例对象在无任何数据指向该对象时,在不定时的某个时刻会被java垃圾处理机制所回收,而栈内存中的一些临时变量啥的,在其变量生命周期结束时其所占用的空间也会被回收。
回复 使用道具 举报
飘过,但也学点知识{:soso_e121:}
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马