堆内存

JVM虚拟机(中)--堆,GC机制

寵の児 提交于 2020-01-23 14:02:18
内容承接上节,上节说到了虚拟机栈,本地方法栈及程序计数器及类的加载等相关内容,这节聊聊上节没提到的元空间,堆及堆上的GC机制,GC的算法将在下节继续说明. java 创建的对象大部分都在堆上存储 ,是GC操作的主体.那么堆在内存如何分配的呢?如下图: 首先堆上分为新生代和老年代,新生代又分为Eden区,From Survivor 区及To Survivor区,新生代上发生的GC叫做Minor GC,老年代发生的GC叫做Major GC或者Full GC. Minor GC速度较快,比较频繁,Major GC/Full GC则速度较慢,是Minor GC 的十分之一以下,一般来说,发生Major GC/Full GC时会伴随至少一次Minor GC. 在谈GC之前,先说说新生代与老年代,新生代中Eden,From Survivor及To Survivor之间的联系.以及触发GC的条件. Eden 区,java生成的对象一开始 大多数 (特例后文会讲)都在Eden区,当Eden区中的对象占用空间越来越大时,会触发Minor GC,此时在Eden区的对象如果是可回收的(下文会对可回收判断逻辑进行解释)则直接回收,而不可回收的部分会被放入From Survivor区. From Survivor区与To Survivor区 ,发送GC时,From Survivor区中的数据

JVM内存堆布局图解分析

我怕爱的太早我们不能终老 提交于 2020-01-22 16:46:14
内存分析(SxtStu.java) Java程序运行在JVM上,可以把JVM理解成Java程序和操作系统之间的桥梁,JVM实现了Java的平台无关性,由此可见JVM的重要性。所以在学习Java内存分配原理的时候一定要牢记这一切都是在JVM中进行的,JVM是内存分配原理的基础与前提。 一个完整的Java程序运行过程会涉及以下内存区域: 寄存器: JVM内部虚拟寄存器,存取速度非常快,程序不可控制。 栈: 保存局部变量的值,包括:a.用来保存基本数据类型的值;b.保存类的 实例 ,即堆区 对象 的引用(指针)。也可以用来保存加载方法时的帧。 堆: 用来存放动态产生的数据,比如new出来的 对象 。注意创建出来的对象只包含属于各自的成员变量,并不包括成员方法。因为同一个类的对象拥有各自的成员变量,存储在各自的堆中,但是他们共享该类的方法,并不是每创建一个对象就把成员方法复制一次。 常量池: JVM为每个已加载的类型维护一个常量池,常量池就是这个类型用到的常量的一个有序集合。包括直接常量(基本类型,String)和对其他类型、方法、字段的 符号引用(1) 。池中的数据和数组一样通过索引访问。由于常量池包含了一个类型所有的对其他类型、方法、字段的符号引用,所以常量池在Java的动态链接中起了核心作用。 常量池存在于堆中 。 代码段: 用来存放从硬盘上读取的源程序代码。 全局数据段:

小内存堆管理算法详细解析

偶尔善良 提交于 2020-01-21 11:51:20
1、小内存堆管理算法介绍 本文所介绍的内存堆管理是RT Thread操作系统中的小内存管理算法,参考mem.c源文件。这个程序适用于小内存的CPU,比如像STM32F这样的只有几十-几百KB内存的处理器。整个内存堆的处理算法简洁,高效,现对其中的原理做详细的介绍。首先先写上整个源代码,如下。内存堆的函数只有主要的4个函数:   rt_system_heap_init   rt_malloc   rt_free   plug_holes /*头文件中的相关宏定义 define in header file*/ #define HEAP_MAGIC 0x1ea0 struct heap_mem { /* magic and used flag */ rt_uint16_t magic; rt_uint16_t used; rt_size_t next, prev; #ifdef RT_USING_MEMTRACE rt_uint8_t thread[4]; /* thread name */ #endif }; /** pointer to the heap: for alignment, heap_ptr is now a pointer instead of an array */ static rt_uint8_t *heap_ptr; /** the last entry,

内存分配堆与栈的区别

时间秒杀一切 提交于 2020-01-21 05:35:34
堆(Heap)与栈(Stack)是开发人员必须面对的两个概念,在理解这两个概念时,需要放到具体的场景下,因为不同场景下,堆与栈代表不同的含义。一般情况下,有两层含义: (1)程序内存布局场景下,堆与栈表示两种内存管理方式; (2)数据结构场景下,堆与栈表示两种常用的数据结构。 1.程序内存分区中的堆与栈 1.1 栈简介 栈由操作系统自动分配释放 ,用于存放函数的参数值、局部变量等,其操作方式类似于数据结构中的栈。参考如下代码: int main() { int b; //栈 char s[] = "abc"; //栈 char *p2; //栈 } 其中函数中定义的局部变量按照先后定义的顺序依次压入栈中,也就是说相邻变量的地址之间不会存在其它变量。栈的内存地址生长方向与堆相反,由高到底,所以后定义的变量地址低于先定义的变量,比如上面代码中变量 s 的地址小于变量 b 的地址,p2 地址小于 s 的地址。栈中存储的数据的生命周期随着函数的执行完成而结束。 1.2 堆简介 堆由开发人员分配和释放, 若开发人员不释放,程序结束时由 OS 回收,分配方式类似于链表。参考如下代码: int main() { // C 中用 malloc() 函数申请 char* p1 = (char *)malloc(10); cout<<(int*)p1<<endl; //输出

五、JVM之堆内存

本秂侑毒 提交于 2020-01-20 13:37:45
堆结构分代图 堆结构分代的意义   Java虚拟机根据对象存活的周期不同,把堆内存划分为几块,一般分为新生代、老年代和永久代(对HotSpot虚拟机而言),这就是JVM的内存分代策略。   堆内存是虚拟机管理的内存中最大的一块,也是垃圾回收最频繁的一块区域,我们程序所有的对象实例都存放在堆内存中。给堆内存分代是为了提高对象内存分配和垃圾回收的效率。试想一下,如果堆内存没有区域划分,所有的新创建的对象和生命周期很长的对象放在一起,随着程序的执行,堆内存需要频繁进行垃圾收集,而每次回收都要遍历所有的对象,遍历这些对象所花费的时间代价是巨大的,会严重影响我们的GC效率。   有了内存分代,情况就不同了,新创建的对象会在新生代中分配内存,经过多次回收仍然存活下来的对象存放在老年代中,静态属性、类信息等存放在永久代中,新生代中的对象存活时间短,只需要在新生代区域中频繁进行GC,老年代中对象生命周期长,内存回收的频率相对较低,不需要频繁进行回收,永久代中回收效果太差,一般不进行垃圾回收,还可以根据不同年代的特点采用合适的垃圾收集算法。分代收集大大提升了收集效率,这些都是内存分代带来的好处。 堆结构分代 ​ Java虚拟机将堆内存划分为新生代、老年代和永久代,永久代是HotSpot虚拟机特有的概念(JDK1.8之后为metaspace替代永久代),它采用永久代的方式来实现方法区

java内存划分为5个部分

两盒软妹~` 提交于 2020-01-19 09:14:09
Java的内存需要划分成为5个部分: 1.栈(Stack) : 存放的都是方法中的局部变量。 方法的运行一定要在栈当中运行。 局部变量:方法的参数,或者是方法{}内部的变量 作用域:一旦超出作用域,立刻从栈内存当中消失。 2.堆(Heap) : 凡是new出来的东西,都在堆当中。 堆内存里面的东西都有一个地址值: 16进制 堆内存里面的数据,都有默认值。规则: 如果是整数 默认为0 如果是浮点数 默认为0.0 如果是字符 默认为"\u0000' 如果是布尔 默认为false 如果是引用类型 默认为null 3.方法区(Method Area) : 存储.class相关信息,包含方法的信息。 4.本地方法栈(Native Method Stack) : 与操作系统相关。 5.寄存器(pc Register) : 与CPU相关。 来源: CSDN 作者: young_change 链接: https://blog.csdn.net/young_changge/article/details/103843336

堆和栈的区别

社会主义新天地 提交于 2020-01-18 14:17:26
void f() { int* p=new int[5]; }   这条短短的一句话就包含了堆与栈,看到 new ,我们首先就应该想到,我们分配了一块堆内存,那么指针 p 呢?他分配的是一块栈内存,所以这句话的意思就是: 在栈内存中存放了一个指向一块堆内存的指针 p 。在程序会先确定在堆中分配内存的大小,然后调用 operator new 分配内存,然后返回这块内存的首地址,放入栈中 , VC6 下的汇编代码如下: 00401028 push 14h 0040102A call operator new (00401060) 0040102F add esp,4 00401032 mov dword ptr [ebp-8],eax 00401035 mov eax,dword ptr [ebp-8] 00401038 mov dword ptr [ebp-4],eax 堆和栈究竟有什么区别? 主要的区别由以下几点:    1 、管理方式不同;    2 、空间大小不同;    3 、能否产生碎片不同;    4 、生长方向不同;    5 、分配方式不同;    6 、分配效率不同;    管理方式:对于栈来讲,是由编译器自动管理,无需我们手工控制;对于堆来说,释放工作由程序员控制,容易产生 memory leak 。   空间大小:一般来讲在 32 位系统下,堆内存可以达到 4G

3.C++基础学习 堆heap栈stack

一世执手 提交于 2020-01-18 08:09:17
栈: 存在于每个作用域(scope)中的一块内存空间,生命期:出了作用域就自动释放,析构函数就被调用,auto object 如果是指针,生命期结束的是指针,原有分配的内存就会泄露 堆 由操作系统提供的一块全局的内存空间,需要手动释放 class Complex { . . . } . . x4 : Complex c4 ( 4 , 5 ) int main ( ) { x1 : Complex c1 ( 1 , 2 ) ; x2 : Comeplex * p = new Complex ( 3 ) ; x3 : static Complex c2 ( 1 , 2 ) } x1 是存在于栈中的 x2是存在于堆中的,因为是向操作系统动态分配了一块内存,当作用域结束后,这个内存仍然在被使用,需要手动释放掉这部分内存,delete掉 x3:生命在作用域结束后仍然run在 x4:是全局函数,作用域是整个程序 来源: CSDN 作者: weixin_43278150 链接: https://blog.csdn.net/weixin_43278150/article/details/103898841

栈与堆

纵饮孤独 提交于 2020-01-17 05:30:42
栈是编译期间就分配好的内存空间,因此代码中必须就栈的大小有明确的定义;局部值类型变量、值类型参数等都在栈内存中 堆是程序运行期间动态分配的内存空间,可以根据程序的运行情况确定要分配的堆内存的大小 #region a->b->c->d 输出 d,c,b,a string[] names = new string[] { "a", "b", "c", "d" }; Stack stack = new Stack(); foreach (string item in names) { stack.Push(item); } while (stack.Count > 0) { Console.WriteLine(stack.Pop()); } #endregion 来源: https://www.cnblogs.com/xiaoweigogo/p/7799925.html

Java内存区域-堆,程序计数器

倖福魔咒の 提交于 2020-01-16 19:58:36
Jvm运行时数据区域-堆,程序计数器 Java堆 堆:Java堆是内存中最大的的一块。Java堆是所有线程共享的的一块内存区域,此内存唯一的目的存放对象实例。几乎所有对象的实例都在这里分配内存。这一点在Java虚拟机规范中描述:所有的对象实例以及数据都要在堆上分配,但是随着JIT编译器的发展与逃逸分析技术逐渐成熟,栈上分配,标量替换优化技术将会导致一下微妙的变化发生,所有的对象都分配在堆上也渐渐的变得不是那么绝对了。 Java堆是垃圾收集器管理的主要区域(GC堆),现在采用分代收集算法,Java堆分为新生代,和老年代;再细致一点有Eden空间,From Survivor空间,To Survivor空间等。从内存分配的角度来看,线程共享的Java堆中可能划分出多个线程私有的分配缓冲区(Thread Local Allocation Buffer,TLAB)。无论如何划分,都与存放的内容无关,无论哪个区域,存放任然都是对象实例,进一步划分的目的是为了更好的回收内存,或者更快的分配内存。 根据Java虚拟机规定,Java堆可以物理不连续的内存空间中,只要逻辑上是连续的即可,就像我们的磁盘空间一样。在实现是,既可以实现固定大小的,也可以是可扩展的,不过当前主流的虚拟机都是按照可扩展实现的(t通过-Xmx和-Xms控制(有遇到过))。如果在堆中没有内存完成实例分配,并且无法在扩展时