`

Java内存分配

阅读更多

前言:

工作时间稍微长一些之后,总是对一些不能看到的东西会有一些好奇,想透过现象能观察到后台的本质情况,能用java语言编写业务逻辑了,但是并不一定能明白每个字符,每个常量在计算机中是怎么存储的,所以有时候在编程过程中可能由于基础知识不扎实而犯了一些很低级但又很严重的错误,也正是掌握了这些基础我想也才知道所以然,也才会有进步。

 

 Java中的内存分配区域主要由:堆、栈、常量池、静态域、代码区

堆(Heap):堆主要存放Java在运行过程中new出来的对象,凡是通过new生成的对象都存放在堆中,对于堆中的对象生命周期的管理由Java虚拟机的垃圾回收机制GC进行回收和统一管理。

栈(Stack):栈主要存放在运行期间用到的一些局部变量(基本数据类型的变量)或者是指向其他对象的一些引用,当一段代码或者一个方法调用完毕后,栈中为这段代码所提供的基本数据类型或者对象的引用立即被释放;另外需注意的是栈中存放变量的值是可以共享的,优先在栈中寻找是否有相同变量的值,如果有直接指向这个值,如果没有则另外分配。

常量池(ConstantPool):常量池在编译期间就将一部分数据存放于该区域,包含基本数据类型如int、long等和对象类型String、数组等并以final声明的常量值。特别注意的是对于运行期位于栈中的String常量的值可以通过 String.intern()方法将该值置入到常量池中。

静态域(StaticSegment):存放类中以static声明的静态成员变量

代码区(CodeSegment):主要存放一些代码段以供类调用的时候所共用。

举例:

	public static void main(String[] args) {

		String a = "a";

		String tempa="a";

		String b = "b";

		String c = "c";

		String abc = "abc";

		String a_b_c = "a"+"b"+"c";

		String a_b = a+b;

		String ab = "ab";

		String newabc = new String("abc");

		String abcintern = newabc.intern();

		final String finalb = "b";

		String a_b2 = "a"+finalb;

		System.out.println(tempa==a);//true,在栈中共享同一个值,也可以理解为他们共同指向字符串常量池中的a

		System.out.println(newabc==abc);//false,newabc是指向堆的一个引用,abc是在位于栈中的String对象的一个引用变量,然后去字符串常量池中找abc字符串,如果找到则将该应用指向abc,如果找不到则将abc放入字符串常量池然后指向它。

		System.out.println(a_b==ab);//false,a_b是在运行期字符串的引用,而ab则是在编译期间就指定了

		System.out.println(a_b_c==abc);//true,a_b_c在编译期间就将常量字符串连接到一起,所以他们指向同一个字符串常量,而且"a"+"b"+"c",首先a和b组装成一个常量ab放于常量池中,然后ab和c组装在一起放于常量池中,然后将abc的地址赋给了a_b_c,由于String是不可变的,所以产生了很多临时变量。

		System.out.println(abcintern==abc);//true,调用intern()方法则将abc字符串放入了字符串常量池,返回值则是直接指向常量池中的字符串常量值所以相等

                     System.out.println(ab==a_b2);//true,finalb是因为声明为final修饰符它在编译时被解析为常量值的一个本地拷贝存储到自己的常量池中,相当于"a"+"b"

	}

 

 

 


 

在面试中我们经常被问到String和StringBuffer的区别,如果从内存上理解了他们的存储那么就不难理解了:以下是JDK中对String的类的说明:

 

public final class String
extends Object
implements Serializable, Comparable<String>, CharSequence

String 类代表字符串。Java 程序中的所有字符串字面值(如 "abc" )都作为此类的实例实现。

字符串是常量;它们的值在创建之后不能更改。字符串缓冲区支持可变的字符串。因为 String 对象是不可变的,所以可以共享。

因为String 字符串是常量,所以他一旦初始化后值是不能变的,而且是可以共享的,存放于字符串常量池,需要在程序中做大量的字符串连接时采用StringBuffer来连接,如果直接采用String来连接由于他们的值是不能改变的,相当于还是采用了StringBuffer来连接了字符串,但是在连接过程中如果事先没声明Stringbuffer对象则中间工程中就会产生很多临时变量:

String str = null;

for(int i=0;i<100;i++){

str +=i;//每循环一次相当于产生了StringBuffer对象

}

 

 

 


 

3
5
分享到:
评论
18 楼 lvjun106 2012-09-03  
liuzhaodong89 写道
System.out.println(tempa==a); 这个语句的执行结果只能证明在
String a = "a";  
  
    String tempa="a";
这种声明方式下,相同的字符串在堆内存中是一个对象。博主这句“栈中存放变量的值是可以共享的”我不太理解。从jvm内存模型看,所有的复杂对象(就是Object的子类)都是放在堆中的,而基本类型的变量都是放在栈中的。如果涉及到栈中数据的共享,应该是针对基本数据类型进行试验吧。


栈中存放了8种基本类型和Reference及ReturnAddress类型
17 楼 crawler 2012-09-02  
tlde_ti 写道
crawler 写道
MrLee23 写道
是在语言的抽象模型很理想的情况下说的...java吗..只能说尽量做到。
tlde_ti 写道
crawler 写道
MrLee23 写道
掌握本质有帮助,不过那不是
tlde_ti 写道
透过现象看本质不是让你去看细节,而是让你看在这之上的抽象模型。

就好像人一样,人的本质绝不是细胞,神经元之类的东西,而是更高层的东西。

掌握细节的确对掌握本质有帮助,不过那不是必须的。而是额外的。

感觉你这种方式适合去学C.

如果你搞java的时候很在乎内存的大小的时候,你就知道内存的了解是多么的重要了。

有道理,因为效率这个东西有你必须从细节入手

natural is best.如果你写的代码是符合抽象模型的,是自然地,那编译器就应该在底层自己去优化它,而不是自己去挖底层,那不是你的活,大部分优化在那个抽象模型之上做就可以了。将程序与底层实现捆绑在一起,既不自然,维护性低,而且底层实现实际上是没有 “保证”的,随时都可能改,只要上层显示的抽象模型没有变化.也即是与底层实现相关的你的程序可能是“不稳定”的.

只有万不得已的时候,才以底层的思路看问题。但那样的代码应该标明做的理由,并且当底层的自身优化已经解决问题的时候。应立即将代码改为 自然的由抽象模型推出 的代码。
------
以上是在语言的抽象模型很理想的情况下说的...java吗..只能说尽量做到。方向要对.

呵呵,只能说你还没有接触到计较内存使用大小的情况。符合抽象模型难道你就能保证你的程序使用的内存是最小最优的么,说个简单的例子,大家都知道的例子,比如我们程序都是完美的设计,都是符合什么抽象,什么面向对象,什么aop,什么ioc,什么模式,等等,都是完美的设计,但是我只在一个方法里面写上一段代码,你就会觉得崩溃了
伪代码:
string a = "";
foreach(int i : list){//此处循环1万次
    a += i + "_";
}

这只不过是个例子,如果我肯定不这么写,所以,细节决定成败,内存同样也是细节的范畴内。

其实我总结这些东西的目的是在工作实践的基础上去理解这些知识,去巩固自己的基础知识,对于细节来说个人觉得很重要,就像如果你被困在一个机关黑屋子里了,这个机关就是个细节,如果找不到打开黑屋子的机关那么你就永远被困在黑屋子里了;另外有的基础知识就像修炼内功一样,内功深厚你出招的杀伤力是不一样,效果是不一样的;每个人都有自己的见解和心得体会,我也觉得很正常,因为出于不同的工作阶段,认识阶段,成长阶段认识是不一样的。


编译器不是考试用的,它不是你的对手,更不是小黑屋,相反他是你的助手。你不信任它提供的抽象模型而什么都要自己做或者自己去看清楚底层实现,这既浪费时间又阻碍了编译器的自由优化。

然后,不要误解我,我并不是反对了解底层,我只是说 那不是“基础”知识,也不是内功,相反,那是“额外”的东西,并非 “必要”的基础。 了解额外的东西当然也是有好处的,因为总是有特殊情况让你不得不去 做底层相关的优化,不过那是 额外的,只有有必需的需要才做。

然后我来提出我认为的java的基础知识,1.语法语义,没有这个你什么也做不了。
2.api类库。没有这个你基本什么都做不了. 3.各种抽象模型,没这个,你不知道怎么做。

ps:算法并不算抽象模型,算法背后的数学抽象概念才算。用算法也就是用,just try it.了解背后的数学才能设计算法。

你说的有道理,所以我说不同的工作阶段,认识阶段,成长阶段每个人都有自己的见解和心得体会。
16 楼 tlde_ti 2012-09-02  
crawler 写道
MrLee23 写道
是在语言的抽象模型很理想的情况下说的...java吗..只能说尽量做到。
tlde_ti 写道
crawler 写道
MrLee23 写道
掌握本质有帮助,不过那不是
tlde_ti 写道
透过现象看本质不是让你去看细节,而是让你看在这之上的抽象模型。

就好像人一样,人的本质绝不是细胞,神经元之类的东西,而是更高层的东西。

掌握细节的确对掌握本质有帮助,不过那不是必须的。而是额外的。

感觉你这种方式适合去学C.

如果你搞java的时候很在乎内存的大小的时候,你就知道内存的了解是多么的重要了。

有道理,因为效率这个东西有你必须从细节入手

natural is best.如果你写的代码是符合抽象模型的,是自然地,那编译器就应该在底层自己去优化它,而不是自己去挖底层,那不是你的活,大部分优化在那个抽象模型之上做就可以了。将程序与底层实现捆绑在一起,既不自然,维护性低,而且底层实现实际上是没有 “保证”的,随时都可能改,只要上层显示的抽象模型没有变化.也即是与底层实现相关的你的程序可能是“不稳定”的.

只有万不得已的时候,才以底层的思路看问题。但那样的代码应该标明做的理由,并且当底层的自身优化已经解决问题的时候。应立即将代码改为 自然的由抽象模型推出 的代码。
------
以上是在语言的抽象模型很理想的情况下说的...java吗..只能说尽量做到。方向要对.

呵呵,只能说你还没有接触到计较内存使用大小的情况。符合抽象模型难道你就能保证你的程序使用的内存是最小最优的么,说个简单的例子,大家都知道的例子,比如我们程序都是完美的设计,都是符合什么抽象,什么面向对象,什么aop,什么ioc,什么模式,等等,都是完美的设计,但是我只在一个方法里面写上一段代码,你就会觉得崩溃了
伪代码:
string a = "";
foreach(int i : list){//此处循环1万次
    a += i + "_";
}

这只不过是个例子,如果我肯定不这么写,所以,细节决定成败,内存同样也是细节的范畴内。

其实我总结这些东西的目的是在工作实践的基础上去理解这些知识,去巩固自己的基础知识,对于细节来说个人觉得很重要,就像如果你被困在一个机关黑屋子里了,这个机关就是个细节,如果找不到打开黑屋子的机关那么你就永远被困在黑屋子里了;另外有的基础知识就像修炼内功一样,内功深厚你出招的杀伤力是不一样,效果是不一样的;每个人都有自己的见解和心得体会,我也觉得很正常,因为出于不同的工作阶段,认识阶段,成长阶段认识是不一样的。


编译器不是考试用的,它不是你的对手,更不是小黑屋,相反他是你的助手。你不信任它提供的抽象模型而什么都要自己做或者自己去看清楚底层实现,这既浪费时间又阻碍了编译器的自由优化。

然后,不要误解我,我并不是反对了解底层,我只是说 那不是“基础”知识,也不是内功,相反,那是“额外”的东西,并非 “必要”的基础。 了解额外的东西当然也是有好处的,因为总是有特殊情况让你不得不去 做底层相关的优化,不过那是 额外的,只有有必需的需要才做。

然后我来提出我认为的java的基础知识,1.语法语义,没有这个你什么也做不了。
2.api类库。没有这个你基本什么都做不了. 3.各种抽象模型,没这个,你不知道怎么做。

ps:算法并不算抽象模型,算法背后的数学抽象概念才算。用算法也就是用,just try it.了解背后的数学才能设计算法。
15 楼 tlde_ti 2012-09-02  
MrLee23 写道
是在语言的抽象模型很理想的情况下说的...java吗..只能说尽量做到。
tlde_ti 写道
crawler 写道
MrLee23 写道
掌握本质有帮助,不过那不是
tlde_ti 写道
透过现象看本质不是让你去看细节,而是让你看在这之上的抽象模型。

就好像人一样,人的本质绝不是细胞,神经元之类的东西,而是更高层的东西。

掌握细节的确对掌握本质有帮助,不过那不是必须的。而是额外的。

感觉你这种方式适合去学C.

如果你搞java的时候很在乎内存的大小的时候,你就知道内存的了解是多么的重要了。

有道理,因为效率这个东西有你必须从细节入手

natural is best.如果你写的代码是符合抽象模型的,是自然地,那编译器就应该在底层自己去优化它,而不是自己去挖底层,那不是你的活,大部分优化在那个抽象模型之上做就可以了。将程序与底层实现捆绑在一起,既不自然,维护性低,而且底层实现实际上是没有 “保证”的,随时都可能改,只要上层显示的抽象模型没有变化.也即是与底层实现相关的你的程序可能是“不稳定”的.

只有万不得已的时候,才以底层的思路看问题。但那样的代码应该标明做的理由,并且当底层的自身优化已经解决问题的时候。应立即将代码改为 自然的由抽象模型推出 的代码。
------
以上是在语言的抽象模型很理想的情况下说的...java吗..只能说尽量做到。方向要对.

呵呵,只能说你还没有接触到计较内存使用大小的情况。符合抽象模型难道你就能保证你的程序使用的内存是最小最优的么,说个简单的例子,大家都知道的例子,比如我们程序都是完美的设计,都是符合什么抽象,什么面向对象,什么aop,什么ioc,什么模式,等等,都是完美的设计,但是我只在一个方法里面写上一段代码,你就会觉得崩溃了
伪代码:
string a = "";
foreach(int i : list){//此处循环1万次
    a += i + "_";
}

这只不过是个例子,如果我肯定不这么写,所以,细节决定成败,内存同样也是细节的范畴内。

如果是我的话,会这么写,mutable object和mutable variable尽量同时只存在一种,方便分析。这里首先看一下String和StringBuilder的抽像.
String : 不可变,每次操作建立一个新对象赋予给变量。
StringBuilder: 可变,用于最终建立一个String(主要目的).

很显然,不可变的String不适合用在for循环里不断变化.而用于中间变化生成 中间值 最终生成 String 结果的 StringBuilder更 natural.
final StringBuilder sb = new StringBuilder();
for (final Integer nj : l) {
  sb.append(nj).append(seperator);
}
final String result = sb.toString();

14 楼 crawler 2012-09-02  
MrLee23 写道
是在语言的抽象模型很理想的情况下说的...java吗..只能说尽量做到。
tlde_ti 写道
crawler 写道
MrLee23 写道
掌握本质有帮助,不过那不是
tlde_ti 写道
透过现象看本质不是让你去看细节,而是让你看在这之上的抽象模型。

就好像人一样,人的本质绝不是细胞,神经元之类的东西,而是更高层的东西。

掌握细节的确对掌握本质有帮助,不过那不是必须的。而是额外的。

感觉你这种方式适合去学C.

如果你搞java的时候很在乎内存的大小的时候,你就知道内存的了解是多么的重要了。

有道理,因为效率这个东西有你必须从细节入手

natural is best.如果你写的代码是符合抽象模型的,是自然地,那编译器就应该在底层自己去优化它,而不是自己去挖底层,那不是你的活,大部分优化在那个抽象模型之上做就可以了。将程序与底层实现捆绑在一起,既不自然,维护性低,而且底层实现实际上是没有 “保证”的,随时都可能改,只要上层显示的抽象模型没有变化.也即是与底层实现相关的你的程序可能是“不稳定”的.

只有万不得已的时候,才以底层的思路看问题。但那样的代码应该标明做的理由,并且当底层的自身优化已经解决问题的时候。应立即将代码改为 自然的由抽象模型推出 的代码。
------
以上是在语言的抽象模型很理想的情况下说的...java吗..只能说尽量做到。方向要对.

呵呵,只能说你还没有接触到计较内存使用大小的情况。符合抽象模型难道你就能保证你的程序使用的内存是最小最优的么,说个简单的例子,大家都知道的例子,比如我们程序都是完美的设计,都是符合什么抽象,什么面向对象,什么aop,什么ioc,什么模式,等等,都是完美的设计,但是我只在一个方法里面写上一段代码,你就会觉得崩溃了
伪代码:
string a = "";
foreach(int i : list){//此处循环1万次
    a += i + "_";
}

这只不过是个例子,如果我肯定不这么写,所以,细节决定成败,内存同样也是细节的范畴内。

其实我总结这些东西的目的是在工作实践的基础上去理解这些知识,去巩固自己的基础知识,对于细节来说个人觉得很重要,就像如果你被困在一个机关黑屋子里了,这个机关就是个细节,如果找不到打开黑屋子的机关那么你就永远被困在黑屋子里了;另外有的基础知识就像修炼内功一样,内功深厚你出招的杀伤力是不一样,效果是不一样的;每个人都有自己的见解和心得体会,我也觉得很正常,因为出于不同的工作阶段,认识阶段,成长阶段认识是不一样的。
13 楼 MrLee23 2012-09-02  
是在语言的抽象模型很理想的情况下说的...java吗..只能说尽量做到。
tlde_ti 写道
crawler 写道
MrLee23 写道
掌握本质有帮助,不过那不是
tlde_ti 写道
透过现象看本质不是让你去看细节,而是让你看在这之上的抽象模型。

就好像人一样,人的本质绝不是细胞,神经元之类的东西,而是更高层的东西。

掌握细节的确对掌握本质有帮助,不过那不是必须的。而是额外的。

感觉你这种方式适合去学C.

如果你搞java的时候很在乎内存的大小的时候,你就知道内存的了解是多么的重要了。

有道理,因为效率这个东西有你必须从细节入手

natural is best.如果你写的代码是符合抽象模型的,是自然地,那编译器就应该在底层自己去优化它,而不是自己去挖底层,那不是你的活,大部分优化在那个抽象模型之上做就可以了。将程序与底层实现捆绑在一起,既不自然,维护性低,而且底层实现实际上是没有 “保证”的,随时都可能改,只要上层显示的抽象模型没有变化.也即是与底层实现相关的你的程序可能是“不稳定”的.

只有万不得已的时候,才以底层的思路看问题。但那样的代码应该标明做的理由,并且当底层的自身优化已经解决问题的时候。应立即将代码改为 自然的由抽象模型推出 的代码。
------
以上是在语言的抽象模型很理想的情况下说的...java吗..只能说尽量做到。方向要对.

呵呵,只能说你还没有接触到计较内存使用大小的情况。符合抽象模型难道你就能保证你的程序使用的内存是最小最优的么,说个简单的例子,大家都知道的例子,比如我们程序都是完美的设计,都是符合什么抽象,什么面向对象,什么aop,什么ioc,什么模式,等等,都是完美的设计,但是我只在一个方法里面写上一段代码,你就会觉得崩溃了
伪代码:
string a = "";
foreach(int i : list){//此处循环1万次
    a += i + "_";
}

这只不过是个例子,如果我肯定不这么写,所以,细节决定成败,内存同样也是细节的范畴内。
12 楼 tlde_ti 2012-09-02  
crawler 写道
MrLee23 写道
掌握本质有帮助,不过那不是
tlde_ti 写道
透过现象看本质不是让你去看细节,而是让你看在这之上的抽象模型。

就好像人一样,人的本质绝不是细胞,神经元之类的东西,而是更高层的东西。

掌握细节的确对掌握本质有帮助,不过那不是必须的。而是额外的。

感觉你这种方式适合去学C.

如果你搞java的时候很在乎内存的大小的时候,你就知道内存的了解是多么的重要了。

有道理,因为效率这个东西有你必须从细节入手

natural is best.如果你写的代码是符合抽象模型的,是自然地,那编译器就应该在底层自己去优化它,而不是自己去挖底层,那不是你的活,大部分优化在那个抽象模型之上做就可以了。将程序与底层实现捆绑在一起,既不自然,维护性低,而且底层实现实际上是没有 “保证”的,随时都可能改,只要上层显示的抽象模型没有变化.也即是与底层实现相关的你的程序可能是“不稳定”的.

只有万不得已的时候,才以底层的思路看问题。但那样的代码应该标明做的理由,并且当底层的自身优化已经解决问题的时候。应立即将代码改为 自然的由抽象模型推出 的代码。
------
以上是在语言的抽象模型很理想的情况下说的...java吗..只能说尽量做到。方向要对.
11 楼 liuzhaodong89 2012-09-01  
crawler 写道
liuzhaodong89 写道
System.out.println(tempa==a); 这个语句的执行结果只能证明在
String a = "a";  
  
    String tempa="a";
这种声明方式下,相同的字符串在堆内存中是一个对象。博主这句“栈中存放变量的值是可以共享的”我不太理解。从jvm内存模型看,所有的复杂对象(就是Object的子类)都是放在堆中的,而基本类型的变量都是放在栈中的。如果涉及到栈中数据的共享,应该是针对基本数据类型进行试验吧。

你说的“这种声明方式下,相同的字符串在堆内存中是一个对象”中的a和tempa并不在堆中,只有通过new出来的对象才为于堆中;
“栈中存放变量的值是可以共享的”你可以理解为对于基本数据类型和常量类型(包括字符常量、字符串常量)都是位于常量池中的,当String a = "a";  执行这句时在栈中声明了一块内存变量a,然后到常量池中去找是否存在字符串常量"a",第一次没找到就将它置入常量池中,此时变量a的值为"a",你也可以理解它指向到常量池中的字符串常量"a";然后执行第二句String tempa="a"; 时,在栈中声明了一块内存变量tempa,然后到常量池中去找是否存在字符串常量"a",此时常量池中已经存在"a",则直接将该值赋给变量tempa,你也可以理解它指向到常量池中的字符串常量"a"(那么相当于他俩都指向常量池中的"a");所以为true。
另外你说的"从jvm内存模型看,所有的复杂对象(就是Object的子类)都是放在堆中的,而基本类型的变量都是放在栈中的"对应String的字符串常量是可以共享的,你可以看JDK中对String类的描述:Strings are constant; their values cannot be changed after they are created. String buffers support mutable strings. Because String objects are immutable they can be shared.(字符串是常量;它们的值在创建之后不能更改。字符串缓冲区支持可变的字符串。因为 String 对象是不可变的,所以可以共享。)

我明白你的意思了。之前是我记错了,字符串的确是放在常量池中的,只是针对你所说的“共享”不太理解你要表达的意思,呵呵
10 楼 crawler 2012-08-31  
liuzhaodong89 写道
System.out.println(tempa==a); 这个语句的执行结果只能证明在
String a = "a";  
  
    String tempa="a";
这种声明方式下,相同的字符串在堆内存中是一个对象。博主这句“栈中存放变量的值是可以共享的”我不太理解。从jvm内存模型看,所有的复杂对象(就是Object的子类)都是放在堆中的,而基本类型的变量都是放在栈中的。如果涉及到栈中数据的共享,应该是针对基本数据类型进行试验吧。

你说的“这种声明方式下,相同的字符串在堆内存中是一个对象”中的a和tempa并不在堆中,只有通过new出来的对象才为于堆中;
“栈中存放变量的值是可以共享的”你可以理解为对于基本数据类型和常量类型(包括字符常量、字符串常量)都是位于常量池中的,当String a = "a";  执行这句时在栈中声明了一块内存变量a,然后到常量池中去找是否存在字符串常量"a",第一次没找到就将它置入常量池中,此时变量a的值为"a",你也可以理解它指向到常量池中的字符串常量"a";然后执行第二句String tempa="a"; 时,在栈中声明了一块内存变量tempa,然后到常量池中去找是否存在字符串常量"a",此时常量池中已经存在"a",则直接将该值赋给变量tempa,你也可以理解它指向到常量池中的字符串常量"a"(那么相当于他俩都指向常量池中的"a");所以为true。
另外你说的"从jvm内存模型看,所有的复杂对象(就是Object的子类)都是放在堆中的,而基本类型的变量都是放在栈中的"对应String的字符串常量是可以共享的,你可以看JDK中对String类的描述:Strings are constant; their values cannot be changed after they are created. String buffers support mutable strings. Because String objects are immutable they can be shared.(字符串是常量;它们的值在创建之后不能更改。字符串缓冲区支持可变的字符串。因为 String 对象是不可变的,所以可以共享。)
9 楼 liuzhaodong89 2012-08-31  
System.out.println(tempa==a); 这个语句的执行结果只能证明在
String a = "a";  
  
    String tempa="a";
这种声明方式下,相同的字符串在堆内存中是一个对象。博主这句“栈中存放变量的值是可以共享的”我不太理解。从jvm内存模型看,所有的复杂对象(就是Object的子类)都是放在堆中的,而基本类型的变量都是放在栈中的。如果涉及到栈中数据的共享,应该是针对基本数据类型进行试验吧。
8 楼 lvjun106 2012-08-31  
对于JAVA内存区域,推荐再看看《JAVA虚拟机规范》,对于不同的JVM,其实现还是有点不同
7 楼 javaboy8282 2012-08-31  
效率貌似都是从这些细节扣出来的!
6 楼 crawler 2012-08-31  
MrLee23 写道
掌握本质有帮助,不过那不是
tlde_ti 写道
透过现象看本质不是让你去看细节,而是让你看在这之上的抽象模型。

就好像人一样,人的本质绝不是细胞,神经元之类的东西,而是更高层的东西。

掌握细节的确对掌握本质有帮助,不过那不是必须的。而是额外的。

感觉你这种方式适合去学C.

如果你搞java的时候很在乎内存的大小的时候,你就知道内存的了解是多么的重要了。

有道理,因为效率这个东西有你必须从细节入手
5 楼 MrLee23 2012-08-31  
希望楼主弄一些如何减少内存开销的例子和心得
4 楼 MrLee23 2012-08-31  
掌握本质有帮助,不过那不是
tlde_ti 写道
透过现象看本质不是让你去看细节,而是让你看在这之上的抽象模型。

就好像人一样,人的本质绝不是细胞,神经元之类的东西,而是更高层的东西。

掌握细节的确对掌握本质有帮助,不过那不是必须的。而是额外的。

感觉你这种方式适合去学C.

如果你搞java的时候很在乎内存的大小的时候,你就知道内存的了解是多么的重要了。
3 楼 crawler 2012-08-31  
tlde_ti 写道
透过现象看本质不是让你去看细节,而是让你看在这之上的抽象模型。

就好像人一样,人的本质绝不是细胞,神经元之类的东西,而是更高层的东西。

掌握细节的确对掌握本质有帮助,不过那不是必须的。而是额外的。

感觉你这种方式适合去学C.

你的见解也不错,更在乎一些底层之上的东西,比如OO思想,算法,模式等。
只不过我觉得理解了内存分配,执行每一行代码都能知道这些东西分配在哪儿,而且有助于对一些概念的真实理解,以前感觉自己的基础是背出来的,现在想好好去理解下这些东西
2 楼 tlde_ti 2012-08-31  
透过现象看本质不是让你去看细节,而是让你看在这之上的抽象模型。

就好像人一样,人的本质绝不是细胞,神经元之类的东西,而是更高层的东西。

掌握细节的确对掌握本质有帮助,不过那不是必须的。而是额外的。

感觉你这种方式适合去学C.
1 楼 hngmduyi 2012-08-31  

相关推荐

Global site tag (gtag.js) - Google Analytics