JAVA内存详解

来源:互联网 发布:算法工程师怎么考 编辑:程序博客网 时间:2024/06/14 20:32

存储器一般分为RAM和ROM两种。

       RAM是随机存储器(内存),ROM是固化存储器(外存)。

RAM存储器在计算机中是作为主存储器使用,用于存放当前正在执行的数据和程序,但所保存的数据和程序却是暂时性的,断电则释放,来电则保存。

ROM存储器能够长期的保存数据资源,而不依靠来电保存,由机械部件带动,存取速度相对于RAM存储器来说,则较慢。一般指的是硬盘、磁盘、光盘等能够长期保存数据的固化硬件。

JVM 会把申请的内存从逻辑上划分为三个区域,即:方法区、堆(stack)与 栈(heap)。

方法区:方法区默认最大容量为64M,Java虚拟机会将加载的java类存入方法区,保存类的结构(属性与方法),类静态成员等内容。
    存放装载的类数据信息:
    基本信息:每个类的全限定名、每个类的直接超类的全限定名、该类是类还是接口、该类型的访问修饰符、直接超接口的全限定名的有序列表。
    详细信息:运行时常量池、字段信息、方法信息、静态变量、到类classloader的引用、到类class的引用

堆:堆内存用来存放由new创建的对象和数组 ;默认最大容量为64M,堆存放对象持有的数据,同时保持对原类的引用。可以简单的理解为对象属性的值保存在堆中,对象调用的方法保存在方法区。

栈:存放基本类型的数据和对象的引用,即存放变量;栈默认最大容量为1M,在程序运行时,每当遇到方法调用时,Java虚拟机就会在栈中划分一块内存称为栈帧(Stack frame),栈帧中的内存供局部变量(包括基本类型与引用类型)使用,当方法调用结束后,Java虚拟机会收回此栈帧占用的内存

 

Java 给我们提供了Runtime 类得到JVM 内存的信息
方法名称 参数作用返回值getRuntime无获取Runtime 对象Runtime 对象totalMemory无获取JVM 分配给程序的内存数量long:内存数量freeMemory无获取当前可用的内存数量long:内存数量maxMemory无获取JVM 可以申请到的最大内存数量long:内存数量
 
 
 
java数据类型 :
 
 
 
 
  

 

基本数据类型(primitive types)

       如  int a = 3; long b = 255L形式定义,称为自动变量。值得注意的是:自动变量存的是字面值,不是类的实例,即不是类的引用,这里并没有类的存在。如 int a = 3; 这里的 a 是一个指向int类型的引用,指向3这个字面值。这些字面值的数据,由于大小可知,生存期可知(这些字面值固定定义在某个程序块里面,程序块退出后,字段值就消失了),出于追求速度的原因,就存在于栈中。

另外,栈有一个很重要的特殊性,就是存在栈中的数据可以共享。假设我们同时定义:
int a = 3; 
int b = 3; 
编译器先处理int a = 3;首先它会在栈中创建一个变量为a的引用,然后查找有没有字面值为3的地址,没找到,就开辟一个存放3这个字面值的地址,
然后将a指向3的地址。接着处理int b = 3;在创建完b的引用变量后,由于在栈中已经有3这个字面值,便将 b 直接指向3的地址,特别注意的是,这种字面值的引用与类对象的引用不同。假定两个类对象的引用同时指向一个对象,如果一个对象引用变量修改了这个对象的内部状态,那么另一个对象引用变量也即刻反映出这个变化。相反,通过字面值的引用来修改其值,不会导致另一个指向此字面值的引用的值也跟着改变的情况。如上例,我们定义完a与b的值后,再令a=4;那么,b不会等于4,还是等于3。在编译器内部,遇到a=4;时,它就会重新搜索栈中是否有4的字面值,如果没有,重新开辟地址存放4的值;如果已经有了,则直接将a指向这个地址。因此a值的改变不会影响到b的值。

 

另一种是包装类数据,如Integer, String, Double等将相应的基本数据类型包装起来的类。这些类数据全部存在于堆中,Java用new()语句来显示地告诉编译器,在运行时才根据需要动态创建,因此比较灵活,但缺点是要占用更多的时间。 4. String是一个特殊的包装类数据。即可以用String str = new String("abc");的形式来创建,也可以用String str = "abc";的形式来创建(作为对比,在JDK 5.0之前,你从未见过Integer i = 3;的表达式,因为类与字面值是不能通用的,除了String。而在JDK 5.0中,这种表达式是可以的!因为编译器在后台进行Integer i = new Integer(3)的转换)。前者是规范的类的创建过程,即在Java中,一切都是对象,而对象是类的实例,全部通过new()的形式来创建。Java中的有些类,如DateFormat类,可以通过该类的getInstance()方法来返回一个新创建的类,似乎违反了此原则。其实不然。该类运用了单例模式来返回类的实例,只不过这个实例是在该类内部通过new()来创建的,而getInstance()向外部隐藏了此细节。那为什么在String str = "abc";中,并没有通过new()来创建实例,是不是违反了上述原则?其实没有

0 0
原创粉丝点击