Java的内存机制

Java 把内存划分成两种:一种是栈内存,另一种是堆内存。在函数中定义的一些基本类型的变量和对象的引用变量都是在函数的栈内存中分配,当在一段代码块定义一个变量时,Java 就在栈中为这个变量分配内存空间,当超过变量的作用域后(比如,在函数A中调用函数B,在函数B中定义变量a,变量a的作用域只是函数B,在函数B运行完以后,变量a会自动被销毁。分配给它的内存会被回收),Java 会自动释放掉为该变量分配的内存空间,该内存空间可以立即被另作它用。

  堆内存用来存放由 new 创建的对象和数组,在堆中分配的内存,由 Java 虚拟机的自动垃圾回收器来管理。在堆中产生了一个数组或者对象之后,还可以在栈中定义一个特殊的变量,让栈中的这个变量的取值等于数组或对象在堆内存中的首地址,栈中的这个变量就成了数组或对象的引用变量,以后就可以在程序中使用栈中的引用变量来访问堆中的数组或者对象,引用变量就相当于是为数组或者对象起的一个名称。引用变量是普通的变量,定义时在栈中分配,引用变量在程序运行到其作用域之外后被释放。而数组和对象本身在堆中分配,即使程序运行到使用 new 产生数组或者对象的语句所在的代码块之外,数组和对象本身占据的内存不会被释放,数组和对象在没有引用变量指向它的时候,才变为垃圾,不能在被使用,但仍然占据内存空间不放,在随后的一个不确定的时间被垃圾回收器收走(释放掉)。这也是 Java 比较占内存的原因,实际上,栈中的变量指向堆内存中的变量,这就是 Java 中的指针!

代码实例Test01:单个对象创建

<ignore_js_op> 
在上述程序中实例化了一个对象per,在实例化对象的过程中需要在内存中开辟空间,这其中就包括栈内存和对内存。具体的内存分配如下图所示:

我们可以从上图中发现,对象名称per被保存在了栈内存中(更加准确的说法是,在栈内存中保存的是堆内存空间的访问地址),而对象的具体内容,比如属性name和age,被保存在了堆内存中。因为per对象只是被实例化,还没有具体被赋值,所以都是默认值。字符串的默认值为null,int类型的默认值为0。前面也已经提到,堆内存空间必须使用new关键字才能开辟。

代码实例Test02:多个对象创建

<ignore_js_op> 
<ignore_js_op>

关键概念:类跟数组一样,都是属于引用类型,引用类型就是指一堆对内存可以同时被多个栈内存指向。下面来看一下引用传递的简单实例。

代码实例Test03:对象引用传递1

<ignore_js_op> 
程序运行结果为:

姓名:张三,年龄:33
姓名:张三,年龄:33

从程序的运行结果可以发现,两个对象输出的内容一样,实际上所谓的引用传递,就是将一个堆内存空间的使用权交个多个栈内存空间,每个栈内存空间都可以修改堆内存空间的内容,此程序的内存分配图如下所示:

<ignore_js_op> 
注意:上述实例中对象per2没有堆内存空间,这是因为对象per2只进行了声明操作,也没有进行实例化操作。只有使用new关键字实例化以后才会有对内存空间。

代码实例Test04:对象引用传递2

<ignore_js_op> 
上述程序运行结果为:

姓名:张三,年龄:30
姓名:张三,年龄:30

从程序的输出结果可以发现可Test03一样。不过内存分配发生了一些变化,具体如下所示:

注意点:

  • Java本身提供垃圾收集机制(Garbage Collection,GC),会不定期施放不用的内存空间,只要对象不用了,就会等待GC释放空间,如上面堆内存中的name="李四";age=33。
  • 一个栈内存只能指向一个对内存空间,如果要想再指向其他的堆内存空间,则必须先断开已有的指向才能分配新的指向。

java中常用的内存区域

在java中主要存在4块内存空间,这些内存的名称及作用如下:

    • 栈内存空间:保存所有的对象名称(更准确地说是保存了引用的堆内存空间的地址)
    • 堆内存空间:保存每个对象的具体属性内容。
    • 全局数据区:保存static类型的属性。
    • 全局代码区:保存所有的方法定义。
时间: 2024-10-08 07:21:00

Java的内存机制的相关文章

Java的内存机制(转)

0.参考资料: http://www.j2megame.org/index.php/content/view/2246/125.html  转自 http://www.cnblogs.com/xwdreamer/archive/2012/04/01/2428857.html 1.Java的内存机制 Java 把内存划分成两种:一种是栈内存,另一种是堆内存.在函数中定义的一些基本类型的变量和对象的引用变量都是在函数的栈内存中分配,当在一段代码块定义一个变量时,Java 就在栈中为这个变量分配内存空

「轉」Java的内存机制

0.参考资料: http://www.j2megame.org/index.php/content/view/2246/125.html 1.Java的内存机制 Java 把内存划分成两种:一种是栈内存,另一种是堆内存.在函数中定义的一些基本类型的变量和对象的引用变量都是在函数的栈内存中分配,当在一段代码块定义一个变量时,Java 就在栈中为这个变量分配内存空间,当超过变量的作用域后(比如,在函数A中调用函数B,在函数B中定义变量a,变量a的作用域只是函数B,在函数B运行完以后,变量a会自动被销

[java基础] java 虚拟机内存机制

了解java虚拟器内存机制的好处 当我们需要解决一些棘手的问题,比如性能优化,解决OOM异常时,如果我们了解java虚拟机的内存机制,就知道从哪里下手处理这些问题了 如何了解 我从三方面去说明他 进程级别 我们在pc上做一个应用,在手机上做一个app,都是以进程的级别存在的.在进程这个级别中,内存被分配给/分配为 java堆.方法区(含有常量存储区).各个线程 java堆:java堆是GC线程回收内存的区域,他主要是用来存储各种对象 方法区:方法区存储了class在加载之后的信息,如全局变量,方

java内存机制

原文:http://www.cnblogs.com/xwdreamer/archive/2012/04/01/2428857.html 1.Java的内存机制 Java 把内存划分成两种:一种是栈内存,另一种是堆内存.在函数中定义的一些基本类型的变量和对象的引用变量都是在函数的栈内存中分配,当在一段代码块定义一个变量时,Java 就在栈中为这个变量分配内存空间,当超过变量的作用域后(比如,在函数A中调用函数B,在函数B中定义变量a,变量a的作用域只是函数B,在函数B运行完以后,变量a会自动被销毁

Java的内存存储

0.参考资料: http://www.j2megame.org/index.php/content/view/2246/125.html 1.Java的内存机制 Java 把内存划分成两种:一种是栈内存,另一种是堆内存.在函数中定义的一些基本类型的变量和对象的引用变量都是在函数的栈内存中分配,当在一段代码块定义一个变量时,Java 就在栈中为这个变量分配内存空间,当超过变量的作用域后(比如,在函数A中调用函数B,在函数B中定义变量a,变量a的作用域只是函数B,在函数B运行完以后,变量a会自动被销

Java垃圾回收机制以及内存泄漏

原文地址 前言 在segmentfault上看到一个问题:java有完善的GC机制,那么在java中是否会出现内存泄漏的问题,以及能否给出一个内存泄漏的案例.本问题视图给出此问题的完整答案. 垃圾回收机制简介 在程序运行过程中,每创建一个对象都会被分配一定的内存用以存储对象数据.如果只是不停的分配内存,那么程序迟早面临内存不足的问题.所以在任何语言中,都会有一个内存回收机制来释放过期对象的内存,以保证内存能够被重复利用. 内存回收机制按照实现角色的不同可以分为两种,一种是程序员手动实现内存的释放

java从基础知识(四)java内存机制

Java内存管理:深入Java内存区域 上面的文章对于java的内存管理机制讲的非常细致,在这里我们只是为了便于后面内容的理解,对java内存机制做一个简单的梳理. 程序计数器:当前线程所执行的字节码的行号指示器,虚拟机下一条需要执行的字节码指令,分支.循环.跳转.异常处理.线程恢复等基础功能都需要依赖改变这个计数器的值来完成. 栈:保存局部变量.引用,方法调用结束即被释放.每个方法被执行的时候都会同时创建一个栈帧(Stack Frame)用于存储局部变量表.操作栈.动态链接.方法出口 等信息.

Java虚拟机内存管理机制

自动内存管理机制 Java虚拟机(JVM)在执行Java程序过程中会把它所管理的内存划分为若干个不同的数据区域.这些区域都有各自的用途,以及创建和销毁的时间,有的区域随着虚拟机进程的启动而存在,有的区域则是依赖用户线程的启动和结束而建立和销毁.根据<Java虚拟机规范 第2版>规定,运行时数据区包括: 1.程序计数器 一块较小的内存空间,不在Ram上,而是直接划分在CPU上的,程序员无法直接操作它.当前线程所执行的字节码的行号指示器,通过改变这个计数器的值来选取下一条需要执行的字节码指令.每条

关于仿照java的内存回收机制实现C++的自动内存回收的一点想法

java的内存回收机制是很高效的,对软件产生的额外影响很小.而在C++中的大多数智能指针都是采用的引用计数的策略实现,当计数到0时,将所指向的指针删除.这种智能指针当应用到比较大的对象或者动态内存分配的次数非常少时.对软件的性能不会有多大的影响,反而提高了对内存的使用效率.可是一旦使用动态内存分配的次数非常巨大的时候.不仅对内存的使用效率下降,软件的运行效率也会下降很多.这主要是因为,动态分配造成的存储碎片化使可用内存减少,cache命中率也会下降.对软件性能可能会造成几百倍的损失. 目前的想法