标王 热搜:
 
当前位置: 首页 » 编程语言 » Java » 正文

JVM的内存分配方式介绍

放大字体  缩小字体 发布日期:2019-04-27  来源:fUsA6G  作者:xinb2b.cn  浏览次数:48
核心提示:本篇文章给大家带来的内容是介绍JVM的内存分配方式,有一定的参考价值,有需要的朋友可以参考一下,希望对你有所帮助。前言本篇


本篇文章给大家带来的内容是介绍JVM的内存分配方式,有一定的参考价值,有需要的朋友可以参考一下,希望对你有所帮助。

前言

本篇讲解在java程序运行时,内存的分配是怎样进行的?

java虚拟机编译时的内存存储有三类:

1、静态(方法区)存储

2、栈式存储

3、堆式存储

静态存储是指在编译的时候就得确定这个数据的存储需求,然后给它分配固定的内存,所以说静态存储不允许有可变的数据结构出现,因为可变的数据不会确定存储空间

栈式存储相比于静态存储正好相反,在编译时,栈式存储指定的存储数据是不确定的,只有真正运行到这个数据的时候才知道,那时候才能为它分配内存空间

堆式存储相对于栈式存储,栈式存储在分配空间前必须指定数据要分配多少内存,而堆式存储则完全无法确定数据结构需要的内存空间,比如可变数组,对象实例,所以堆是由大片的可利用块和空闲块组成

栈和堆

静态存储相对简单,所以我们着重分析栈和堆的关系和区别

区别
在栈中的数据一旦超过它的作用域之后,就会被释放,内存会被其他数据占用
在堆中,分配的内存是由java虚拟机自动垃圾回收器管理,这些可变数组、对象在没有引用变量指向他们的时候,才会变成垃圾,但仍然占着内存,之后再一个不确定的时间被垃圾回收器释放掉

在一个JVM实例中,堆区只有一个,而栈可以有多个

关系
在堆中创建一个数据之后,可以在栈中定义一个变量,这个变量指向堆中的某个数据(指向数据的首地址),也就是说这个变量变成了堆中数据的引用变量,可以利用引用变量来访问堆中的数据,这就是java的指针。

并且每个java应有都会有一个JVM实例,每个实例对应一个堆,在这个应有运行期间,所有的类实例和数组都放在这个堆中,在建立一个对象的时候会从两个地方分配内存,在堆中是这个对象的实际值,而在栈(堆栈,也叫stack)中,分配的是堆中这个对象的索引

堆栈(stack)

先看下这张图(嗯 画的很形象)

1.png

JVM是基于堆栈的,每新建一个线程会分配一个堆栈,它是以帧为单位,有先进后出的特性(看图可懂)

当激活一个java方法时,就为往堆栈中放入一个帧(这就是压栈),在这个方法的执行过程中,这个帧就会用来保存数据

方法的存在有堆栈决定,而由于先进后出的形式,方法之间嵌套的越深,stack的内存就越难释放,所以递归这样的方法本人不推荐使用

下面贴出压栈和出栈的具体实现

使用压栈出栈来将字符串倒序

String value = "test 1234567890";
StringBuffer result = new StringBuffer();
 
Stack stack = new Stack();
 
for(char c : value.toCharArray()) {
  stack.push(c);
}
 
while (!stack.empty()) {
  result.append(stack.pop());
}
 
value = result.toString();

相关视频教程推荐:《Java教程

以上就是本篇文章的全部内容,希望能对大家的学习有所帮助。更多精彩内容大家可以关注fUsA6G

 
关键词: 分配
 
[ 编程语言搜索 ]  [ 加入收藏 ]  [ 告诉好友 ]  [ 打印本文 ]  [ 违规举报 ]  [ 关闭窗口 ]
 
推荐图文
Java数组如何反转? Java基础:封装、方法重载、构造方法(构造函数)的介绍
Java web用的比较多的框架是什么? CommandLineRunner与ApplicationRunner的介绍
推荐编程语言
点击排行
 
网站首页 | 关于我们 | 联系方式 | 使用协议 | 版权隐私 | 网站地图 | 排名推广 | 广告服务 | 积分换礼 | 网站留言 | RSS订阅