Java中的栈上分配
博客搬家自https://my.oschina.net/itsyizu/blog/
什么是栈上分配
栈上分配是java虚拟机提供的一种优化技术,基本思想是对于那些线程私有的对象(指的是不可能被其他线程访问的对象),可以将它们打散分配在栈上,而不是分配在堆上。分配在栈上的好处是可以在函数调用结束后自行销毁,而不需要垃圾回收器的介入,从而提供系统的性能。
栈上分配的一个技术基础是进行逃逸分析。逃逸分析的目的是判断对象的作用域是否有可能逃逸出函数体。
下面的代码显示了一个逃逸的对象:
public class PartionOnStack {
static class User{
private int id;
private String name;
public User(){}
}
private static User user;
public static void foo() {
user=new User();
user.id=1;
user.name="sixtrees";
}
public static void main(String[] args) {
foo();
}
}
因为上面的代码中的User的作用域是整个Main Class,所以user对象是可以逃逸出函数体的。下面的代码展示的则是一个不能逃逸的代码段。
public class PartionOnStack {
class User{
private int id;
private String name;
public User(){}
}
public void foo() {
User user=new User();
user.id=1;
user.name="sixtrees";
}
public static void main(String[] args) {
PartionOnStack pos=new PartionOnStack();
pos.foo();
}
}
代码来帮忙
通过上面的分析,我们知道java虚拟机会帮助我们在栈上进行分配,我们设置了1亿次alloc的对象创建,每个User对象实例需要占用16字节的空间,如果没有优化,累计的空间申请将有1.5GB这么大,如果我们的堆空间设置的值小于1.5GB的话,就会发生GC。代码如下:
public class PartionOnStack {
class User{
public int id;
public String name;
}
public void foo() {
User user=new User();
user.id=1;
user.name="sixtrees";
}
public static void main(String[] args) {
System.out.println("start-----------");
long beginTime=System.currentTimeMillis();
PartionOnStack pos=new PartionOnStack();
for(int i=0;i<100000000;i++)
{
pos.foo();
}
long endTime=System.currentTimeMillis();
System.out.println("总共运行----"+(endTime-beginTime)+"ms");
}
}
使用下面的参数运行上面的代码
-server -XMX10m -Xms10m -XX:+DoEscapeAnalysis -XX:+PrintGC -XX:-UseTLAB -XX:+EliminateAllocations
运行的结果如下所示:

对于大量的零散小对象,栈上分配提供了一种很好的对象分配策略,栈上分配的速度快,并且可以有效地避免垃圾回收带来的负面的影响,但由于和堆空间相比,栈空间比较小,因此对于大对象无法也不适合在栈上进行分配。
Java中的栈上分配的更多相关文章
- Java对象栈上分配
转自 https://blog.csdn.net/o9109003234/article/details/101365108 在学习Java的过程中,很多喜欢说new出来的对象分配一定在对上: 其实不 ...
- JVM之对象分配:栈上分配 & TLAB分配
1. Java对象分配流程 2. 栈上分配 2.1 本质:Java虚拟机提供的一项优化技术 2.2 基本思想: 将线程私有的对象打散分配在栈上 2.3 优点: 2.3.1 可以在函数调用结束后自行销毁 ...
- 浅谈Java中的栈和堆
人们常说堆栈堆栈,堆和栈是内存中两处不一样的地方,什么样的数据存在栈,又是什么样的数据存在堆中? 这里浅谈Java中的栈和堆 首先,将结论写在前面,后面再用例子加以验证. Java的栈中存储以下类型数 ...
- 【深入浅出-JVM】(7):栈上分配
概念 对那些作用于不会逃逸出方法的对象,在分配内存时,不在将对象分配在堆内存中,而是将对象属性打散后分配在线程私有栈内存上,这样随着方法调用结束,栈上分配打散的对象也被回收掉,不在增加 GC 额外压力 ...
- Java中的栈,堆,方法区和常量池
要说Java中的栈,堆,方法区和常量池就要提到HotSpot,HotSpot是Sun JDK 和 Open JDK中所带的虚拟机. (Sun JDK 和 Open JDK除了注释不同,代码实现基本上是 ...
- 【LWJGL3】LWJGL3的内存分配设计,第一篇,栈上分配
简介 LWJGL (Lightweight Java Game Library 3),是一个支持OpenGL,OpenAl,Opengl ES,Vulkan等的Java绑定库.<我的世界> ...
- LWJGL3的内存管理,第二篇,栈上分配
LWJGL3的内存管理,第二篇,栈上分配 简介 为了讨论LWJGL在内存分配方面的设计,本文将作为该系列随笔中的第二篇,用来讨论在栈上进行内存分配的策略,该策略在 LWJGL3 中体现为以 Memor ...
- 如何限制一个类只在堆上分配和栈上分配(StackOnly HeapOnly)
[本文链接] http://www.cnblogs.com/hellogiser/p/stackonly-heaponly.html [题目] 如何限制一个类只在堆上分配和栈上分配? [代码] C+ ...
- Java 中数组的内存分配
Java 中数组的内存分配 1.Java 程序在运行时,需要在内存中分配空间.为了提高运算效率,就对空间进行了不同区域的划分,因为每一片区域都有特定的处理数据和内存管理方式. 2.数组基本概念 数组是 ...
随机推荐
- 基于 Spring MVC 的开源测试用例管理系统以及开发自测的实践
早前公司领导提出让开发自测,测试么也做做开发.当然了,为了保证自测质量,测试用例仍需测试提供,所以为了提高开发自测的效率和质量,我们开发了捉虫记.捉虫记是一个完整的Spring MVC项目,现已开源, ...
- JavaScript ES5面向对象实现一个todolist
todo-list 前言 遵守 开始 布局 设计对象 对象的属性 事件绑定 业务逻辑单元的操作 实例化对象 参考 todo-list 前言 最近阅读了JavaScript设计模式的面向对象篇,但是又苦 ...
- Spark源码分析之分区器的作用
最近因为手抖,在Spark中给自己挖了一个数据倾斜的坑.为了解决这个问题,顺便研究了下Spark分区器的原理,趁着周末加班总结一下~ 先说说数据倾斜 数据倾斜是指Spark中的RDD在计算的时候,每个 ...
- 使用NPOI生成Excel级联列表
目录 1 概要 1 2 磨刀不误砍柴工——先学会Excel中的操作 2 3 利用NPOI生成导入模板 7 3.1 设置workbook&sheet ...
- STM32学习笔记(三)——外部中断的使用
开发板芯片:STM32F407ZGT6 硬件连接:PE3-KEY1 一.STM32F4的中断介绍 STM32F4的每个IO都可以作为外部中断输入,很强大的功能吧!以前学习的51只有两个外部中断. ST ...
- 第五章 HQL实用技术
第五章 HQL实用技术5.1 使用HQL查询语句(面向对象查询语句) 5.1.1 编写HQL语句 5.1.1.1 from子句 例:fr ...
- CF #271 F Ant colony 树
题目链接:http://codeforces.com/contest/474/problem/F 一个数组,每一次询问一个区间中有多少个数字可以整除其他所有区间内的数字. 能够整除其他所有数字的数一定 ...
- 使用vue-cli构建多页面应用+vux(一)
众所皆知,vue对于构建单页面应该相当方便,但是在项目中难免遇到有多个页面的情况. 1.先安装vue-cli脚手架,具体步骤看vue-cli的官方github地址 https://github.com ...
- C#总结(二)事件Event 介绍总结
最近在总结一些基础的东西,主要是学起来很难懂,但是在日常又有可能会经常用到的东西.前面介绍了 C# 的 AutoResetEvent的使用介绍, 这次介绍事件(event). 事件(event),对于 ...
- bzoj4816 [Sdoi2017]数字表格
Description Doris刚刚学习了fibonacci数列.用f[i]表示数列的第i项,那么 f[0]=0 f[1]=1 f[n]=f[n-1]+f[n-2],n>=2 Doris用老师 ...