Java如何进行内存分配

Java 虚拟机(JVM)负责管理 Java 应用程序的内存。在 Java 中,内存被划分为不同的区域,每个区域都有不同的用途。

Java 中有两种主要的内存区域:堆和栈。

  1. 功能:

(1)堆:堆是存储所有对象实例的内存区域。所有对象实例都存储在堆中,并且所有线程都可以共享这些对象。

(2)栈:栈是存储局部变量和方法调用的内存区域。每当方法被调用时,JVM 都会在栈上创建一个新的帧,存储该方法的所有局部变量和活动信息。

  1. 性能与存储要求:

(1)栈的性能比堆要快,仅次于位于CPU中的寄存器。但是,在分配内存的时候,存放在栈中的数据大小与生存周期必须在编译时是确定的,缺乏灵活性。

(2)堆可以动态分配内存大小,编译器不必知道要从堆里分配多少存储空间,生存周期也不必事先告诉编译器,Java的垃圾收集器会自动收走这些不再使用的数据,因此可以得到更大的灵活性。但是,由于要在运行时动态分配内存和销毁对象时都需要占用时间,所以效率低。由于面向对象的多态性,堆内存分配是必不可少的,因为多态变量所需的存储空间只有在运行时创建了对象之后才能确定。当然,为达到这种灵活性,必然会付出一定的代价。

  1. 内存的分配和回收

Java中的数据类型有两种:一种是8个基本类型(即int, short, long, byte, float, double, boolean, char),一种是引用类型。

(1)函数中基本类型和对象的引用都是在栈内存中分配。当在一段代码块中定义一个变量时,由于这些变量大小可知,生存期可知,出于追求速度的原因,Java就在栈中为这个变量分配内存空间,当超过变量的作用域后,Java会自动释放掉为该变量所分配的内存空间。

(2)对于引用类型:Java中所有对象的存储空间都是在堆中分配的,但是这个对象的引用却是在堆栈中分配。也就是说在建立一个对象时,从两个地方都分配内存,在堆中分配的内存实际用于建立这个对象,而在栈中分配的内存只是一个指向这个堆对象的引用而已。在堆中分配的内存,由Java虚拟机的自动垃圾回收器来管理。

当 Java 应用程序启动时,JVM 会为其分配一定数量的内存。随着应用程序的运行,JVM 会动态分配堆和栈的内存,以确保应用程序有足够的内存可用。如果内存不足,JVM 会触发垃圾回收,回收那些不再被使用的对象。

Java 中的内存分配是由 JVM 自动管理的,开发人员无需关心内存分配的细节。但是,理解 Java 的内存结构和如何管理内存是了解 Java 程序性能和可靠性的关键。

思考—为什么有人说Java比较慢

在Java中,除了简单的基本数据类型,其它都是在堆中分配内存,这也是程序慢的原因之一。

如果没有GC( Garbage Collection 垃圾回收机制),上面的说法就是成立的。堆不像栈是连续的空间,没法指望堆本身的内存分配能够象栈一样拥有传送带般的速度,因为谁会为你整理庞大的堆空间,让你几乎没有延迟的从堆中获取新的空间呢?

这个时候,GC站出来解决问题。GC清除内存垃圾,为堆腾出空间供程序使用,但GC同时也担负了另外一个重要的任务,就是要让Java中堆的内存分配和其他语言中堆栈的内存分配一样快。要达到这样的目的,就必须使堆的分配也能够做到像传送带一样,不用自己操心去找空闲空间。所以,GC除了负责清除Garbage外,还要负责整理堆中的对象,把它们转移到一个远离Garbage的纯净空间中无间隔的排列起来,就像堆栈中一样紧凑,这样Heap Pointer就可以方便的指向传送带的起始位置,或者说一个未使用的空间,为下一个需要分配内存的对象"指引方向"。因此可以这样说,垃圾收集影响了对象的创建速度。

那GC怎样在堆中找到所有存活的对象呢?前面说了,在建立一个对象时,在堆中分配实际建立这个对象的内存,而在栈中分配一个指向这个堆对象的引用,那么只要在栈(也有可能在静态存储区)找到这个引用,就可以跟踪到所有存活的对象。找到之后,GC将它们从堆的一个块中移到另一个块中,并将它们一个挨一个地排列起来,这样就可以在速度可以保证的情况下,可以任意分配的。

但是,GC的运行要占用一个线程,这本身就是一个降低程序运行性能的缺陷,更何况这个线程还要在堆中把内存翻来覆去的折腾。不仅如此,如上面所说,堆中存活的对象被搬移了位置,那么所有对这些对象的引用都要重新赋值,这些开销都会导致性能的降低。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值