JVM中内存分配策略及堆和栈的比较
最近愈发对JVM底层的运行 原理产生了兴趣,遂查阅相关资料以备忘。
内存分配策略
根据编译原理的观点,程序运行时的内存分配,有三种策略,分别为静态的、堆式的、栈式的。
静态存储分配指的是在编译时就能确定每个数据目标在运行时的存储空间需求,因而在编译时就给它们分配了固定的内存空间。这种分配方式要求程序代码中不能有可变数据结构(例如可变数组)的存在,也不允许有嵌套或者递归的结构出现,因为它们都会导致编译时编译程序无法准确计算所需的存储空间大小。
栈式存储分配也可以成为动态存储分配,是由一个类似于堆栈的运行栈来实现的。和静态存储分配相反,在栈式分配方案中,程序对于存储空间的需要在编译时是未知的,只有在运行的时候才能知道。但是规定在运行进入一个程序模块时,必须要知道该程序模块所需的数据区大小才能为其分配内存。同我们日常了解的栈一致,栈式存储分配遵照先进后出的原则进行分配。
堆式存储分配专门负责在编译时或运行时程序模块入口处都无法确定存储要求的数据结构的分配,比如可变长度串和对象实例。堆内存由大片的可利用块或空闲块组成,堆中的内存也可以根据任意的顺序进行分配和释放。
堆和栈的比较
从通俗化的角度来说,堆是用来存放对象的,栈是用来存放执行程序的
在编程中,例如在C/C++中,所有的方法调用都是通过栈来进行的,所有的局部变量、形式参数也都是通过栈来分配内存的。使用的时候,根据栈的工作原理,从栈顶向上用即可,Stack Pointer会自动指引程序到存储位置,程序只需要进行存储即可。退出函数的时候,修改栈指针即可将栈中存储的内容销毁。这种模块速度最快,适合用户存储执行程序。但是应当注意的是,在进行内存分配是,比如为一个即将要调用的程序模块分配数据区时,应当实现知道这个所需数据区的大小,也就是说虽然分配工作是在运行程序的时候进行的,但是分配的大小是在运行程序之前就知道的,这个是编译时确定的,而不是运行时。
堆是应用程序在运行过程中请求操作系统给分配的内存,由于是操作系统管理的内存分配,所以在分配和销毁是都需要占用时间,因此堆的工作效率比较低。但是堆的优点在于,编译器不需要知道从堆中分配了多少的内存空间,也不需要知道存储的数据要在堆中停留多长的时间,这也就使得用堆来保存数据有着更大的灵活性。事实上,面向对象的多态性的实现,堆内存的分配必不可少,因为多态对象所需的数据区大小只有在运行时确定了对象以后才能知道。在java中,创建对象只需要使用new关键字即可,执行这些代码时,就会在堆中自动进行数据的保存。也就是因为这种灵活分配存储空间的特性,堆内存分配的工作效率不高。
JVM中的堆和栈
堆和栈都是java用来在内存中存放数据的地方,与C++不同的是,java自动管理堆和栈,程序员不能自行设置堆和栈。
java中的堆就是运行时存储数据的区域,类的实例对象可以通过new、new Array等指令建立从中分配空间,这些空间不需要程序代码来显式释放。堆是由jvm自动垃圾回收器负责的,堆的优势是可以动态的分配内存大小,生存周期也不用实现告诉编译器,因为空间是在运行时动态进行内存分配的。如果堆中的数据确认为垃圾,则jvm的自动垃圾回收器汇自动回收相应的空间。但是缺点是,由于实在运行时动态进行空间分配,存取速度较慢。
栈的优势是:存取的速度都比堆要快,仅次于寄存器。栈数据可以共享,但是缺点时,栈空间中的数据大小和生存期必须是确定的,缺乏灵活性。栈主要存放一些基本类型的变量int, short, long, byte, float, double, boolean, char和对象句柄。
栈有一个很重要的特殊性,就是存在栈中的数据可以共享。假设我们同时定义:
int a = 3;
int b = 3;
编译器先处理int a = 3;首先它会在栈中创建一个变量为a的引用,然后查找栈中是否有3这个值,如果没找到,就将3存放进来,然后将a指向3。接着处理int b = 3;在创建完b的引用变量后,因为在栈中已经有3这个值,便将b直接指向3。这样,就出现了a与b同时均指向3的情况。这时,如果再令a=4;那么编译器会重新搜索栈中是否有4值,如果没有,则将4存放进来,并令a指向4;如果已经有了,则直接将a指向这个地址。因此a值的改变不会影响到b的值。要注意这种数据的共享与两个对象的引用同时指向一个对象的这种共享是不同的,因为这种情况a的修改并不会影响到b, 它是由编译器完成的,它有利于节省空间。而一个对象引用变量修改了这个对象的内部状态,会影响到另一个对象引用变量。
参考:https://www.jianshu.com/p/947a76e2ddbc
JVM中内存分配策略及堆和栈的比较的更多相关文章
- java中内存分配策略及堆和栈的比较
Java把内存分成两种,一种叫做栈内存,一种叫做堆内存 在函数中定义的一些基本类型的变量和对象的引用变量都是在函数的栈内存中分配.当在一段代码块中定义一个变量时,java就在栈中为这个变量分配内存空间 ...
- JVM总结(二):JVM的内存分配策略
这节我们总结一下JVM中的内存分配策略.目录如下: 内存分配策略 对象优先在新生代Eden分配 大对象直接进入老年代 长期存活的对象将进入老年代 动态对象年龄判定 空间分配担保 内存分配策略 Java ...
- 【面试必备】小伙伴栽在了JVM的内存分配策略。。。
周末有小伙伴留言说上周面试时被问到内存分配策略的问题,但回答的不够理想,小伙伴说之前公号里看过这一块的文章的,当时看时很清楚,也知道各个策略是干嘛的,但面试时脑子里清楚,心里很明白,但嘴里就是说不清楚 ...
- JVM学习--内存分配策略(持续更新)
一.前言 最近学习<深入java虚拟机>,目前看到内存分配策略这块.本文将进行一些实践. 二.内存分配策略 1.大对象直接进入老年代 书中提到了: 下面进行测试,代码如下: public ...
- JVM的内存分配策略
1.对象优先在Eden区分配大多数情况下,对象在新生代Eden区中分配.当Eden区没有足够空间进行分配时,虚拟机将发起一次Minor GC. 2.大对象直接进入老年代 所谓的大对象是指,需要大量连续 ...
- java虚拟机学习-JVM内存管理:深入垃圾收集器与内存分配策略(4)
Java与C++之间有一堵由内存动态分配和垃圾收集技术所围成的高墙,墙外面的人想进去,墙里面的人却想出来. 概述: 说起垃圾收集(Garbage Collection,下文简称GC),大部分人都把这项 ...
- JVM内存分配策略
在 JVM内存垃圾回收方法 中,我们已经详细讨论了内存回收,但是,我们程序中生成的对象是如何进行分配的呢?以下所述针对的是HotSpot虚拟机. 1.Java堆结构 以HotSpot为例,如下图: H ...
- JVM的内存分配与垃圾回收策略
自动内存管理机制主要解决了两个问题:给对象分配内存以及回收分配给对象的内存. >>垃圾回收的区域 前面的笔记中整理过虚拟机运行数据区,再看一下这个区域: 注意在这个Runtime Data ...
- jvm系列 (二) ---垃圾收集器与内存分配策略
垃圾收集器与内存分配策略 前言:本文基于<深入java虚拟机>再加上个人的理解以及其他相关资料,对内容进行整理浓缩总结.本文中的图来自网络,感谢图的作者.如果有不正确的地方,欢迎指出. 目 ...
随机推荐
- vue路由传参页面刷新参数丢失问题解决方案
最近项目中涉及到跨页面传参数和后台进行数据交互,看到需求之后第一反应就是用路由传参来解决:Vue中给我们提供了三种路由传参方式,下面我们一个一个的来看一下: 方法一:params传参: this.$r ...
- Dubbo源码解析之SPI(一):扩展类的加载过程
Dubbo是一款开源的.高性能且轻量级的Java RPC框架,它提供了三大核心能力:面向接口的远程方法调用.智能容错和负载均衡,以及服务自动注册和发现. Dubbo最早是阿里公司内部的RPC框架,于 ...
- 峰哥说技术:10-Spring Boot静态资源处理
Spring Boot深度课程系列 峰哥说技术—2020庚子年重磅推出.战胜病毒.我们在行动 10 峰哥说技术:Spring Boot静态资源处理 今天我们聊聊关于 Spring Boot 中关于静 ...
- django setting文件那些事
1.设置语言.时区 2.设置新建的用户表作为默认用户表 3.利用apps文件夹收纳app 新建python package apps,然后把app放在该文件夹下 然后setting中添加如下代码: 4 ...
- Python数据科学手册(2) NumPy入门
NumPy(Numerical Python 的简称)提供了高效存储和操作密集数据缓存的接口.在某些方面,NumPy 数组与 Python 内置的列表类型非常相似.但是随着数组在维度上变大,NumPy ...
- C++ 文件操作 FILE*
#define _CRT_SECURE_NO_WARNINGS #include <stdio.h> //编程题:往文件里写入字母表的26个字母. //要求:如果字母对应编码值 是奇数则写 ...
- vue之冒泡阻止
用了Element ui写页面 <el-dropdown-menu slot="dropdown"> <el-dropdown-item> <el-s ...
- mysql 多个字段重复记录查询
select * from productstockquantity t where () ORDER BY t.CombinationI
- WPF学习概述
引言 在桌面开发领域,虽然在某些领域,基于electron的跨平台方案能够为我们带来某些便利,但是由于WPF技术能够更好的运用Direct3D带来的性能提升.以及海量Windows操作系统和硬件资源的 ...
- (转)协议森林14 逆袭 (CIDR与NAT)
协议森林14 逆袭 (CIDR与NAT) 作者:Vamei 出处:http://www.cnblogs.com/vamei 欢迎转载,也请保留这段声明.谢谢! IPv4由于最初的设计原因,长度只有32 ...