最近学习中遇到了些疑惑,希望 v2 各位大牛解惑。
先说 js ,限定在 ES5 讨论。在 js 中对象是存在堆内存中的,变量只是个引用,那对象的属性是存在哪的呢,假设该属性是个数字 3 ,函数作用域中的变量又是存在哪里呢。
再说 java , static 修饰的静态变量我理解为和 js 构造函数本身的属性是类似的东西,这东西存在哪块内存,局部变量存在哪块内存,类 new 出的对象中实例变量又存在哪里。
问题总结:下面两段 java 和 js 代码中, demo.num1 , DemoJava.num2 , num3 , num4 , obj1.num5 , arr1[0]都存在内存哪里?
public class DemoJava {
public int num1 = 1;
public static int num2 = 2;
public static void main(String[] args) {
DemoJava demo = new DemoJava();
int num3 = 3;
System.out.println("num1:" + demo.num1);
System.out.println("num2:" + DemoJava.num2);
System.out.println("num3:" + num3);
}
}
var fun1, obj1, arr1;
function add() {
var num4 = 4;
}
obj1 = {
num5: 5
};
arr1 = [6, 7];
1
diangdiang 2017-04-26 14:42:26 +08:00
小白强行回答,貌似 java 类静态变量存在在方法区,局部变量存在栈,通过 new 生成的对象存在堆里,
《深入理解 Java 虚拟机》有详细介绍。 |
2
araraloren 2017-04-26 14:42:50 +08:00
~~很好奇
学 js/java 的人会对这个感兴趣么 |
3
murmur 2017-04-26 14:45:59 +08:00
如果是 java 的话其实不绝对,因为你不知道虚拟机把你的东西都优化到哪里去了。。。
|
4
peneazy OP @diangdiang 也看到别人说有个方法区的地方
|
5
peneazy OP @araraloren 没搞明白有些不舒服。。
|
7
sagaxu 2017-04-26 15:18:37 +08:00
Java 的 Static 存在 Run-Time Constant Pool 里。但是知道它存哪里,毫无意义啊。
|
8
sagaxu 2017-04-26 15:22:32 +08:00
@peneazy Java 代码如何编译成字节码, JVM 又如何执行和优化, GC 具体是怎么工作的,这些全搞明白,可以读个博了。把 Java 搞懂了, Java 那么多框架和库,把细节搞明白一遍,没个二三十年恐怕不行。
|
9
gxbb097528 2017-04-26 16:47:32 +08:00
最近在看网易云课堂的 Java 基础视频,讲的有这些,但是讲的是大概,没有特别深究,要深究真跟楼上说的一样要几个好几年功夫,看看视频了解个大概还行
|
10
geelaw 2017-04-26 16:52:19 +08:00
纠结 JavaScript 的内存布局没有意义, JavaScript 把它抽象掉了。
|
12
jun4rui 2017-04-26 17:38:12 +08:00 via Android
java 的类是引用类型,自然是在堆里面,所有同类共用一块地址
|
15
Ouyangan 2017-04-26 19:25:36 +08:00
@diangdiang #1 Java8 已经没持久代的概念了 , 也直接在堆上分配内存了.. 详情可以 google 下
|
16
jun4rui 2017-04-26 21:06:42 +08:00
```javascript
var fun1, obj1, arr1; //对于 js 来说, function 这种引用值一般是保存在堆内存中的 function add() { var num4 = 4; } //对象也是, js 中的对象一般是存放在堆内存。所以{num5:5}是保存在堆内存中 obj1 = { num5: 5 }; //数组也是存放在堆内存 arr1 = [6, 7]; ``` 对于函数作用域应该还是这个标准, function 、 obj 、 array 是在堆,其他基本是在栈 |
17
phx13ye 2017-04-26 21:56:10 +08:00
实例基本类型和对象一起在堆
静态基本类型和 class 一起在 permgen 或 metaspace 方法基本类型和栈帧一起在栈 |
18
runjvm 2017-04-27 00:02:32 +08:00 2
前面很多同学说的都不太准确。
以 HotSpot 8 为例,静态变量并不存放在方法区或者 PermGen 或者 MetaSpace ,每一个类被解析后都有一个对应的 mirror 对象,这个对象是 java.lang.Class 类型,“方法区”存的只是元数据,譬如描述类的结构、各字段分别什么类型之类的,每一个类的元数据有个指针指向这个对应的 mirror 对象,静态变量是这个 mirror 对象的一个字段, mirror 对象不是只有那些静态变量对应的字段,它还有许多其他的字段用于 reflection 。而 mirror 对象其实都在堆上,于是静态变量作为其一个字段也在堆上。一个 Java 程序一旦运行其实最开始被分配的那些对象就是 primitive 类型对应的 mirror 对象。 所以短答案是,静态变量的元数据在方法区,但是静态本身在堆上。 至于前面同学说的逃逸分析,逃逸分析只在编译优化时发生,在解释器里 new 出来的实例对象总是在堆里。 |
19
okcdz 2017-04-27 01:03:16 +08:00 via iPhone 1
回答 js 的问题吧, java 不了解。你这个不是 es5 的问题,而是编译器的问题。对象保存在堆内存里面,对象属性也是。至于小整形,在 v8 实现里面是直接传递的,在 Chakra 里面也是保存在堆里面,然后引用传递。至于函数里的变量,那是运行时分配的空间,当然也是分配在堆里面的。
|
20
araraloren 2017-04-28 08:37:43 +08:00
|
21
peneazy OP @araraloren 是啊 已经不纠结这块了,不如多做几道算法题来的爽~
|