successfulroof
2013-06-21 21:08
浏览 365
已采纳

Java 属性 在JVM中保存的地方 的问题

遇到一个难题,来iteye问一下,一直以来有几个疑问,关于成员变量在jvm中保存的位置有一些疑问。

class TestObject {

public static Object objstatic = new Object();

public int i = 1;

public static int j = 2;

private String privateString = "private";

public static void main(String [] args) {
TestObject to = new TestObject();
}
}

问题1:TestObject 类里面有四个属性,初始化对象时,这四个属性分别保存在内存中的哪儿?
问题2:objstatic/i/j/privateString 这四个引用保存在内存中的哪儿?

麻烦讲详细一点,谢谢各位了。。跪谢!

  • 写回答
  • 关注问题
  • 收藏
  • 邀请回答

8条回答 默认 最新

  • dsm02955299 2013-06-22 20:57
    已采纳

    objstatic/j 在方法区
    i/privateString 在堆上
    作用域在方法内的变量,会在当前栈上申请空间。基本变量的,保存的是变量的值,对象或者数组的话,保存的是指针,指向堆上该对象/数组的位置。
    所以你在方法里,new TestObject()的时候是在堆上申请一块空间的,当TestObject obj = 的时候在栈上申请一块空间,存放指向堆上内存的位置。
    至于static的变量的话,是在类加载时候已经申请好的了,这块区域叫做方法区。其存放的内容也和栈上的类似,基本类型存放值,引用类型存储指针。
    每个对象在堆上的存储结构中,会在头部有一个对象头,对象头里保存着对象锁信息,更重要的是一个指向其类定义方法区的指针。所以你使用obj.j也是可以访问到值的,虽然会在编译时有警告。

    已采纳该答案
    打赏 评论
  • u011066523 2013-06-21 21:27

    寄存器:我们在程序中无法控制

    [color=red]栈:存放基本类型的数据和对象的引用,但对象本身不存放在栈中,而是存放在堆中[/color]

    堆:存放用new产生的数据

    静态域:存放在对象中用static定义的静态成员

    常量池:存放常量

    非RAM存储:硬盘等永久存储空间

    打赏 评论
  • zyn010101 2013-06-21 21:48
    打赏 评论
  • teasp 2013-06-21 21:51

    objstatic这个引用应该在方法区里面,对象则应该在堆中。
    i这个变量应该和这个TestObject对象一起放在堆中。
    j应该在方法区里。
    privateString放在常量池里。

    打赏 评论
  • clxy大叔 2013-06-21 22:22

    不是回答问题,是来请教的。因为这方面经验很是贫瘠。

    在什么样的场景里——即需要解决什么样的问题时,会需要这方面的知识?

    比如,调查内存泄漏吗?

    打赏 评论
  • zw19861028 2013-06-22 00:25

    一般有两种,
    栈(Stack):连续的存储单元,比较宝贵,存放基本类型的数据和对象的引用
    堆(Heap):分撒的存储单元,存放用new产生的对象
    当执行Object o = new Object();o的引用放在Stack,o里的基本的数据成员也放在Stack中,其他要在Heap。
    我这边有本《深入java虚拟机.pdf》,不厚,言简意赅,可以很好的解决你的问题。
    希望能对你有帮助:
    http://download.csdn.net/detail/zw19861028/5628247

    打赏 评论
  • cxzucc 2013-06-22 00:51

    说下个人理解,请大家多多指正。

    静态变量的创建,从JVM角度而言是在方法区(Method Area),对于特定的实现的话,例如Oracle HotSpot而言是在持久区(Permanent Area),方法区或持久区,也叫栈内存。
    public static Object objstatic = new Object();

    基本类型的实例变量,在线程栈中。
    public int i = 1;

    基本类型的静态变量,应该也是在方法区
    public static int j = 2;

    字符串比较特殊,这种方式的话,会在常量池(属于方法区)中创建对象
    private String privateString = "private";

    打赏 评论
  • zjphzxg 2013-06-22 07:50

    public static Object objstatic = new Object(); //objstatic :方法区,new Object() :堆

    public int i = 1; // 堆

    public static int j = 2; // 方法区

    private String privateString = "private"; // privateString:堆,"private":方法区

    打赏 评论

相关推荐 更多相似问题