在方法(代码块)中定义一个变量时,java就在栈中为这个变量分配JVM内存空间,当超过变量的作用域后,java会自动释放掉为该变量所分配的JVM内存空间;而在堆中分配的JVM内存由java虚拟机的自动垃圾回收器来管理。
JVM内存区域组成
JVM内存分四种:
1、栈区(stacksegment)—由编译器自动分配释放,存放函数的参数值,局部变量的值等,具体方法执行结束之后,系统自动释放JVM内存资源
2、堆区(heapsegment)—一般由程序员分配释放,存放由new创建的对象和数组,jvm不定时查看这个对象,如果没有引用指向这个对象就回收
3、静态区(datasegment)—存放全局变量,静态变量和字符串常量,不释放
4、代码区(codesegment)—存放程序中方法的二进制代码,而且是多个对象共享一个代码空间区域
==========================
Java中变量内存分配机制
在本文中,简单的为大家介绍有关,java中变量在内存是如何分配的。
在任何编程语言中,无论是基本类型还是引用类型,不论其作用域如何,都必须为其分配一定的内存空间,Java 语言也不例外,Java 的数据类型可以分为两种:基本类型(变量持有数据本身的值)和引用类型(是某个对象的引用,而并非是对象本身);基本类型包括:boolean、float、double、int、long、short、byte以及char;在Java编程语言中除基本类型以外其余都是引用类型如:类类型、数组类型等。
在计算机内存中主要来自四个地方:heap segment(堆区)、stack segment(栈区)、codesegment(代码区)、data segment(数据区);不同的地方存放不同数据:其中堆区主要存放Java程序运行时创建的所有引用类型都放在其中;栈区主要存放Java程序运行时所需的局部变量、方法的参数、对象的引用以及中间运算结果等数据;代码区主要存放Java的代码;数据区主要存放静态变量及全局变量;以下结合实例来探讨其具体机制。
class Student { private String name; private int age; public Student(String name, int age) { this.name = name; this.age = age; } } public class Test { static int i = 10; public static void main(String[] args) { Student s1 = new Student(“feng”, 21); } } |
当该程序运行起来后,其计算机内存分布大致如下:
对象在内部表示Java虚拟机规范并没有规定其在堆中是如何表示的。对象的内部的表示会直接影响到堆区的设计以及垃圾收集器(GC)的设计。
Java在堆中的表示方法具体有两种:
把堆分成两个部分:一个句柄池,一个对象池;表示如下图所示:
用对象指针直接指向一组数据,而该数据包括对象实例数据以及指向方法区中的数据的指针,具体如下图所示:
小结:通过对对象内存分配的分析,来使读者对Java的底层有一个比较理性的认识,从而进一步掌握Java的基础知识。在深入了解了Java内存的分配以后,才能为以后编写高质量的程序打下坚实的基础,而且可以借鉴该思想来分析其它面向对象语言的内存分配问题。
http://blog.csdn.net/yitian20000/article/details/6358837
类的方法使用和内存分配
http://blog.csdn.net/mafan121/article/details/39269307
内存分配:堆、栈、方法区
堆:存储new出来的对象实例(包括成员变量)
栈:存储局部变量,引用。调用方法时,栈中分配该方法的栈帧,栈帧中包括参数和局部变量。当方法执行结束时,栈帧被清除,局部变量失效。
方法区:存储类的信息(.class及方法)和静态变量,方法只有一份,通过this区分对象。
http://blog.csdn.net/yitian20000/article/details/6358837
1、栈区(stack)— 由编译器自动分配释放 ,存放函数的参数值,局部变量的值等。其
操作方式类似于数据结构中的栈。
2、堆区(heap) — 一般由程序员分配释放, 若程序员不释放,程序结束时可能由OS回
收 。注意它与数据结构中的堆是两回事,分配方式倒是类似于链表,呵呵。
3、全局区(静态区)(static)—,全局变量和静态变量的存储是放在一块的,初始化的
全局变量和静态变量在一块区域, 未初始化的全局变量和未初始化的静态变量在相邻的另
一块区域。 - 程序结束后由系统释放。
4、文字常量区 —常量字符串就是放在这里的。 程序结束后由系统释放
5、程序代码区—存放函数体的二进制代码。
c#静态方法和实例方法的内存分配问题
https://social.msdn.microsoft.com/Forums/sharepoint/zh-CN/cf143c51-7e6f-4e4e-bdd0-6f148170bec5/c
是static还是non-static的方法,都只存在一份代码,也就是只占用一份内存空间。多了一个this参数
《Effective C#》读书笔记——了解.NET内存管理机制<.NET资源管理>
http://www.tarena.com.cn/netjswz/20121023/814.html
原则:有使用不能收回,使用中的关联者对象不能收回。
数据被回收,方法不会被回收,优化算法是具体是按代回收。
能管理的数据,使用统一规则进行回收,不能管理的外部数据和对象,需要开发者协助,实现使用Dispose方法。
程序员只管创建,不管回收,由虚拟机中的别一个程序即GC服务来执行。在堆上查找很少使用的对象,以收回内存,需要时可以再建。
GC:垃圾回收器,一个类,自动执行或内存不够时调用,或人工调用。
垃圾回收由以下步骤组成:
-
垃圾回收器搜索托管代码中引用的托管对象。
-
垃圾回收器尝试完成没有被引用的对象。
-
垃圾回收器释放没有被引用的对象并回收它们的内存。