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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 郑文博 中级黑马   /  2012-6-1 19:38  /  1615 人查看  /  6 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

本帖最后由 郑文博 于 2012-6-2 09:16 编辑

对方法区跟内存关系的疑问
拿单例设计模式举例:
  1. class Single
  2. {
  3.         
  4.         private static Single s = new Single();
  5.         private Single(){}
  6.         public static Single getInstance()
  7.         {
  8.                 return s;
  9.         }
  10. }

  11. class SingleDemo
  12. {
  13.         public static void main(String[] args)
  14.         {
  15.                 Single s1 = Single.getInstance();
  16.         }
  17. }
复制代码
如此时方法区中的Single类 s 创建一个类中对象 new Single(),此对象存放在堆内存中,堆内存地址付给 s ,此时方法区指向堆内存。下面以调用方法区的 getInstance() 方法时,s 付给了 s1 。因此 s 的地址值给了栈内存 main 中的 s1 了。 从这看出方法区既不占用堆内存也不在栈内存中,那方法区就不占用内存吗?对这很疑惑,求高手解答一下。

--------------------------------------编辑后分隔----------------------------------------
在此多谢大家的解答,尤其是二楼给的帮助。

评分

参与人数 1技术分 +1 收起 理由
赵志勇 + 1 赞一个!

查看全部评分

6 个回复

倒序浏览
本帖最后由 刘伯阳 于 2012-6-1 20:04 编辑

方法区肯定也是要占用内存的啊。只不过是一块特殊的区域。虚拟机可以根据应用动态调整它的大小,方法区也不必是连续的。
当JVM装载一个class文件时,它会从这个class文件所包含的二进制数据中解析出类型信息,然后把这些类型信息放到方法区(线程共享)。
对每个加载的类型,jvm必须在方法区中存储以下类型信息:
一 这个类型的完整有效名
二 这个类型直接父类的完整有效名(除非这个类型是interface或是java.lang.Object,两种情况下都没有父类)
三 这个类型的修饰符(public,abstract, final的某个子集)
四 这个类型直接接口的一个有序列表
回复 使用道具 举报
首先你要搞清楚Java对内存的化分,       
java在内存中一共划分了五块区:堆、栈、方法区、本地方法区、寄存区

JVM在启动的时候默认分配内存空间是64MB,这64MB空间就划分成了五块。
不管是哪个区都是内存的一部分,只不过堆内存相对要分配的大一些。
这里要搞清楚,static修饰的成员在类加载的时候就进去方法区了,它的生命周期是最长的。也就是说当你输也java命令里到程序结束它一直在内存中。
但是堆中的对象就不一定了。

评分

参与人数 1技术分 +1 收起 理由
袁錦泰 + 1 赞一个!

查看全部评分

回复 使用道具 举报
提出提问后请及时查看别人的解答。
回复 使用道具 举报
当你理解了static这个修饰字,你就会知道方法区中的东西是占内存;   方法区中可以存放一切static修饰的成员变量、常量以及方法,而且方法区中存放的东西生命周期最长,它是随着类的加载而加载,可以说是 “比翼双飞”   与   “  唇亡齿寒” ;
回复 使用道具 举报
首先要说下java中内存分配的常识
1.寄存器:最快的存储区, 由编译器根据需求进行分配,我们在程序中无法控制.
2. 栈:存放基本类型的变量数据和对象的引用,但对象本身不存放在栈中,而是存放在堆(new 出来的对象)或者常量池中(字符串常量对象存放在常量池中。)
3. 堆:存放所有new出来的对象。
4. 静态域 :存放静态成员(static定义的)
5. 常量池 :存放字符串常量和基本类型常量(public static final)。
6. 非RAM存储:硬盘等永久存储空间
类中包含基本数据类型、变量数据、静态成员、基本类型常量.....而这些元素是类中的某一部分  你能说类放在内存中的具体哪个地方吗,
而我们运行某个程序(java编辑器)时是要加载到内存上的,我们定义一个类说明我们正在通过编辑器操作操作它,它当然就在内存当中了
当我们编写完某个程序时通过javac命令编辑生成.class文件。当我们不使用时它是保存在硬盘上的。
再想使用它时就要通过java中有个叫类加载器的东西把它加载到内存当中使用

程序的运行都是在内存中进行
回复 使用道具 举报
你平时用堆和栈用的多了,是不是感觉内存就这两块区域
内存大体分四块:
因为我看的英文书所以就不翻译了
1.code segment
2.data segment
3.stack
4.heap
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马