Java对象的生命周期-内存分配、回收内存

SAR ADC和sigma delta ADC的区别 0、ADC基本概念 ADC,即analog to digital converter,模拟到数字的转换器,简称模数转换器。 为什么需要ADC?因为现实的世界中,电信号是连续的,例如心电信号,或者声音信号,这些连续的信号被称为“模拟信号”。 图1:心电信号 图2:声音信号 然而这种连续的信号是无法被计算机处理的,计算机只认识0和1组成的“数字信号“。ADC就充当了这样一个桥梁,将“模拟信号”转换为计算机能识别的“数字信号”。举个例子,当前的心电电压为1.2V(实际没有这么高),ADC可能会得 阅读详情

转自:http://www.uml.org.cn/j2ee/201301183.asp

Java对象的生命周期
 
 
要理解java对象的生命周期,我们需要要明白两个问题,

1、java是怎么分配内存的 ,2、java是怎么回收内存的。

喜欢java的人,往往因为它的内存自动管理机制,不喜欢java的人,往往也是因为它的内存自动管理。我属于前者,这几年的coding经验让我认识到,要写好java程序,理解java的内存管理机制

是多么的重要。任何语言,内存管理无外乎分配和回收,在C中我们可以用malloc动态申请内存,调用free释放申请的内存;在C++中,我们可以用new操作符在堆中动态申请内存,编写析构函数

调用delete释放申请的内存;那么在java中究竟是内存怎样管理的呢?要弄清这个问题,我们首先要了解java内存的分配机制,在java虚拟机规范里,JVM被分为7个内存区域,但是规范这毕竟只

是规范,就像我们编写的接口一样,虽然最终行为一致,但是个人的实现可能千差万别,各个厂商的JVM实现也不尽相同,在这里,我们只针对sun的Hotspot虚拟机讨论,该虚拟机也是目前应用

最广泛的虚拟机。

虚拟器规范中的7个内存区域分别是三个线程私有的和四个线程共享的内存区,线程私有的内存区域与线程具有相同的生命周期,它们分别是: 指令计数器、 线程栈和本地线程栈,四个共享区

是所有线程共享的,在JVM启动时就会分配,分别是:方法区、 常量池、直接内存区和堆(即我们通常所说的JVM的内存分为堆和栈中的堆,后者就是前面的线程栈)。接下来我们逐一了解这几

个内存区域。

1 指令计数器。我们都知道java的多线程是通过JVM切换时间片运行的,因此每个线程在某个时刻可能在运行也可能被挂起,那么当线程挂起之后,JVM再次调度它时怎么知道该线程要运行那条字

节码指令呢?这就需要一个与该线程相关的内存区域记录该线程下一条指令,而指令计数器就是实现这种功能的内存区域。有多少线程在编译时是不确定的,因此该区域也没有办法在编译时分配

,只能在创建线程时分配,所以说该区域是线程私有的,该区域只是指令的计数,占用的空间非常少,所以虚拟机规范中没有为该区域规定OutofMemoryError。

2、线程栈。先让我看以下一段代码:

  class Test{
    public static void main(String[] args) {
       Thread th = new Thread();
       th.start();
    }
  }
 

在运行以上代码时,JVM将分配一块栈空间给线程th,用于保存方法内的局部变量,方法的入口和出口等,这些局部变量包括基本类型和对象引用类型,这里可能有人会问,java的对象引用不是

分配在堆上吗?有这样疑惑的人,可能是没有理解java中引用和对象之前的区别,当我们写出以下代码时:

  public Object test()
  {
     Object obj = new Object();
     return obj;
  }
 

其中的Object obj就是我们所说的引用类型,这样的声明本身是要占用4个字节,而这4个字节在这里就是在栈空间里分配的,准确的说是在线程栈中为test方法分配的栈帧中分配的,当方法退出

时,将会随栈帧的弹出而自动销毁,而new Object()则是在堆中分配的,由GC在适当的时间收回其占用的空间。每个栈空间的默认大小为0.5M,在1.7里调整为1M,每调用一次方法就会压入一个

栈帧,如果压入的栈帧深度过大,即方法调用层次过深,就会抛出StackOverFlow,,SOF最常见的场景就是递归中,当递归没办法退出时,就会抛此异常,Hotspot提供了参数设置改区域的大小,

使用-Xss:xxK,就可以修改默认大小。

3、本地线程栈。顾名思义,该区域主要是给调用本地方法的线程分配的,该区域和线程栈的最大区别就是,在该线程的申请的内存不受GC管理,需要调用者自己管理,JDK中的Math类的大部分方

法都是本地方法,一个值得注意的问题是,在执行本地方法时,并不是运行字节码,所以之前所说的指令计数器是没法记录下一条字节码指令的,当执行本地方法时,指令计数器置为undefined。

接下来是四个线程共享区。

1、方法区。这块区域是用来存放JVM装载的class的类信息,包括:类的方法、静态变量、类型信息(接口/父类),我们使用反射技术时,所需的信息就是从这里获取的。

2、常量池。当我们编写如下的代码时:

  class Test1{
     private final int size=50;
  }
 

这个程序中size因为用final修饰,不能再修改它的值,所以就成为常量,而这常量将会存放在常量区,这些常量在编译时就知道占用空间的大小,但并不是说明该区域编译就固定了,运行期也

可以修改常量池的大小,典型的场景是在使用String时,你可以调用String的 intern(),JVM会判断当前所创建的String对象是否在常量池中,若有,则从常量区取,否则把该字符放入常量池并

返回,这时就会修改常量池的大小,比如JDK中java.io.ObjectStreamField的一段代码:

  ....
  ObjectStreamField(Field field, boolean unshared, boolean showType) {
     this.field = field;
     this.unshared = unshared;
     name = field.getName();
     Class ftype = field.getType();
     type = (showType || ftype.isPrimitive()) ? ftype : Object.class;
     signature = ObjectStreamClass.getClassSignature(ftype).intern();
  }
 

这段代码将获取的类的签名放入常量池。HotSpot中并没有单独为该区域分配,而是合并到方法区中。

3、直接内存区。直接内存区并不是JVM可管理的内存区。在JDK1.4中提供的NIO中,实现了高效的R/W操作,这种高效的R/W操作就是通过管道机制实现的,而管道机制实际上使用了本地内存,这

样就避免了从本地源文件复制JVM内存,再从JVM复制到目标文件的过程,直接从源文件复制到目标文件,JVM通过DirectByteBuffer操作直接内存。

4、堆。主角总是最后出场,堆绝对是JVM中的一等公民,绝对的主角,我们通常所说的GC主要就是在这块区域中进行的,所有的java对象都在这里分配,这也是JVM中最大的内存区域,被所有线

程共享,成千上万的对象在这里创建,也在这里被销毁。

java内存分配到这就算是一个完结了,接下来我们将讨论java内存的回收机制,内存回收主要包含以下几个方面理解:

第一,局部变量占用内存的回收,所谓局部变量,就是指在方法内创建的变量,其中变量又分为基本类型和引用类型。如下代码:

  ...
  public void test()
  {
     int x=1;
     char y='a';
     long z=10L;
  }
 

变量x y z即为局部变量,占用的空间将在test()所在的线程栈中分配,test()执行完了后会自动从栈中弹出,释放其占用的内存,再来看一段代码:

  ....
  public void test2()
  {
     Date d = new Date();
     System.out.println("Now is "+d);
  }
 

我们都知道上述代码会创建两个对象,一个是Date d另一个是new Date。Date d叫做声明了一个date类型的引用,引用就是一种类型,和int x一样,它表明了这种类型要占用多少空间,在java

中引用类型和int类型一样占用4字节的空间,如果只声明引用而不赋值,这4个字节将指向JVM中地址为0的空间,表示未初始化,对它的任何操作都会引发空指针异常。

如果进行赋值如d = new Date()那么这个d就保存了new Date()这个对象的地址,通过之前的内存分配策略,我知道new Date()是在jvm的heap中分配的,其占用的空间的回收我们将在后面着重

分析,这里我们要知道的是这个Date d所占用的空间是在test2()所在的线程栈分配的,方法执行完后同样会被弹出栈,释放其占用的空间。

第二,非局部变量的内存回收,在上面的代码中new Date()就和C++里的new创建的对象一样,是在heap中分配,其占用的空间不会随着方法的结束而自动释放需要一定的机制去删除,在C++中必须

由程序员在适当时候delete掉,在java中这部分内存是由GC自动回收的,但是要进行内存回收必须解决两问题:那些对象需要回收、怎么回收。判定那些对象需要回收,我们熟知的有以下方法:

一,引用计数法,这应是绝大数的的java 程序员听说的方法了,也是很多书上甚至很多老师讲的方法,该方法是这样描述的,为每个对象维护一个引用计数器,当有引用时就加1,引用解除时就

减1,那些长时间引用为0的对象就判定为回收对象,理论上这样的判定是最准确的,判定的效率也高,但是却有一个致命的缺陷,请看以下代码:

  package com.mail.czp;
 
  import java.util.ArrayList;
  import java.util.List;
 
  public class Test {
 
    private byte[] buffer;
    private List ls;
 
    public Test() {
      this.buffer = new byte[4*1024*1024];
      this.ls = new ArrayList();
    }
    private List getList() {
      return ls;
    }
 
    public static void main(String[] args) {
      Test t1 = new Test();
      Test t2 = new Test();
      t1.getList().add(t2);
      t2.getList().add(t1);
      t1 = t2 = null;
      Test t3 = new Test();
      System.out.println(t3);
    }
  }
 

我们用以下参数运行:-Xmx10M -Xms10M M 将jvm的大小设置为10M,不允许扩展,按引用计数法,t1和t2相互引用,他们的引用计数都不可能为0,那么他们将永远不会回收,在我们的环境中JVM

共10M,t1 t2占用8m,那么剩下的2M,是不足以创建t3的,理论上应该抛出OOM。但是,程序正常运行了,这说明JVM应该是回收了t1和t2的我们加上-XX:+PrintGCDetails运行,将打印GC的回收

日记:

  [GC [DefNew: 252K->64K(960K), 0.0030166 secs][Tenured: 8265K->137K(9216K), 0.0109869 secs] 8444K->137K(10176K),
[Perm : 2051K->2051K(12288K)], 0.0140892 secs] [Times: user=0.01 sys=0.00, real=0.02 secs]
  com.mail.czp.Test@2ce908
  Heap
   def new generation   total 960K, used 27K [0x029e0000, 0x02ae0000, 0x02ae0000)
    eden space 896K,   3% used [0x029e0000, 0x029e6c40, 0x02ac0000)
    from space 64K,   0% used [0x02ad0000, 0x02ad0000, 0x02ae0000)
    to   space 64K,   0% used [0x02ac0000, 0x02ac0000, 0x02ad0000)
   tenured generation   total 9216K, used 4233K [0x02ae0000, 0x033e0000, 0x033e0000)
     the space 9216K,  45% used [0x02ae0000, 0x02f02500, 0x02f02600, 0x033e0000)
   compacting perm gen  total 12288K, used 2077K [0x033e0000, 0x03fe0000, 0x073e0000)
     the space 12288K,  16% used [0x033e0000, 0x035e74d8, 0x035e7600, 0x03fe0000)
  No shared spaces configured.
 

从打印的日志我们可以看出,GC照常回收了t1 t2,这就从侧面证明jvm不是采用这种策略判定对象是否可以回收的。

二,根搜索算法,这是当前的大部分虚拟机采用的判定策略,GC线程运行时,它会以一些特定的引用作为起点称为GCRoot,从这些起点开始搜索,把所用与这些起点相关联的对象标记,形成几条

链路,扫描完时,那些没有与任何链路想连接的对象就会判定为可回收对象。具体那些引用作为起点呢,一种是类级别的引用:静态变量引用、常量引用,另一种是方法内的引用,如之前的

test()方法中的Date d对new Date()的引用,在我们的测试代码中,在创建t3时,jvm发现当前的空间不足以创建对象,会出发一次GC,虽然t1和t2相互引用,但是执行t1=t2=null后,他们不和

上面的3个根引用中的任何一个相连接,所以GC会判定他们是可回收对象,并在随后将其回收,从而为t3的创建创造空间,当进行回收后发现空间还是不够时,就会抛出OOM。

接下来我们就该讨论GC 是怎么回收的了,目前版本的Hotspot虚拟机采用分代回收算法,它把heap分为新生代和老年代两块区域,如下图:

 

默认的配置中老年代占90% 新生代占10%,其中新生代又被分为一个eden区和两个survivor区,每次使用eden和其中的一个survivor区,一般对象都在eden和其中的一个survivor区分配,但是那

些占用空间较大的对象,就会直接在老年代分配,比如我们在进行文件操作时设置的缓冲区,如byte[] buffer = new byte[1024*1024],这样的对象如果在新生代分配将会导致新生代的内存不

足而频繁的gc,GC运行时首先会进行会在新生代进行,会把那些标记还在引用的对象复制到另一块survivor空间中,然后把整个eden区和另一个survivor区里所有的对象进行清除,但也并不是立

即清除,如果这些对象重写了finalize方法,那么GC会把这些对象先复制到一个队列里,以一个低级别的线程去触发finalize方法,然后回收该对象,而那些没有覆写finalize方法的对象,将会

直接被回收。在复制存活对象到另一个survivor空间的过程中可能会出现空间不足的情况,在这种情况下GC回直接把这些存活对象复制到老年代中,如果老年代的空间也不够时,将会触发一次

Full GC,Full gc会回收老年代中那些没有和任何GC Root相连的对象,如果Full GC后发现内存还是不足,将会出现OutofMemoryError。

Hotspot虚拟机下java对象内存的分配和回收就算完结了,后续我们将讨论java代码的重构
 
 

基于STM32、HAL库的TLV320AIC3204IRHBR音频接口芯片驱动程序设计 * 开启所有数字部分 */#define TLV320AIC3204_REG_LEFT_HEADPHONE_OUT_VOLUME 0x0C /* 左声道耳机输出音量 */#define TLV320AIC3204_REG_DIGITAL_AUDIO_PATH_CONTROL 0x05 /* 数字音频路径控制 */#define TLV320AIC3204_REG_ANALOG_HP_FILTER_CONTROL 0x34 /* 模拟耳机滤波器控制 *//* 最大音量 */ 阅读详情

相关推荐

从零开始:手把手教你检查并更新英伟达GPU驱动和CUDA版本(Windows/Linux双平台)

本文详细指导如何在Windows和Linux系统上检查并更新英伟达GPU驱动和CUDA版本,解决版本不匹配导致的常见问题。涵盖驱动更新、CUDA Toolkit安装、版本冲突排解及性能优化技巧,帮助开发者高效管理GPU计算环境。

weixin_29237635的博客 701

JVM对象从创建到销毁的过程

从创建对象A来谈谈对象的创建到销毁 A a = new A(); 1、用户创建了一个对象A,运行时JVM首先会去方法区寻找该对象的类信息,没有则使用类加载器ClassLoader加载A.class字节码文件 过程:类加载过程 采用双亲委派机制对类进行加载,加载的类信息存放于一块称为方法区的内存空间,除了类信息外,方法区还存放运行时常量池信息 ,常量,静态变量; 分三个阶段 加载: 1 -通过一个类的全限定名获取此类的二进制字节流 2- 将这个字节流文件所代表的静态存储结构转化为 方法...

weixin_47672692的博客 1757

Cesium实战:3DTiles模型分层分户抽屉效果实现全攻略(附完整代码)

本文详细解析了在Cesium中为3DTiles模型实现分层分户抽屉效果的核心原理与完整代码。通过“主-副双模型”策略,结合属性过滤与矩阵变换,开发者能够创建出可交互、可探索的动态建筑可视化效果,适用于数字孪生、智慧城市及BIM可视化等场景。

d6e7f8g9h的博客 290

Java 对象从创建到毁灭的过程

Step1:类加载检查 虚拟机遇到⼀条 new 指令时,⾸先将去检查这个指令的参数是否能在常量池中定位到这个类的符号引⽤,并且检查这个符号引⽤代表的类是否已被加载过、解析和初始化过。如果没有,那必须先执⾏相应的类加载过程。 加载:获取二进制流,并加载到方法区,并在堆中生成一个java.lang.Class对象,作为方法区这个类的访问入口。 验证:验证字节流是否符合虚拟机的标准 ,比如开头为CA FE BA BE。 准备:为类变量(static)分配内存(注意,逻辑上的方法区,实际上的堆)和零值(初值)。 解

weixin_42042852的博客 1773

史上最全的Logisim运算器实验教程(基于华中科技大学计算机组成原理实验)

本博客是实现了Logisim的运算器设计,有具体的运算器设计的思路和运算器设计的电路,适合一步一步的按照思路做。

qq_62325622的博客 4万+

M2DGR数据集在一些SLAM框架上的配置与运行:ORB-SLAM系列、VINS-Mono、LOAM系列、FAST-LIO系列、hdl_graph_slam

为了说明以上这些SLAM框架的测试与数据集适配,以M2DGR数据集为例进行各自的配置与运行,方便我以后适配自己的数据集,运行的SLAM框架包括:ORB-SLAM2、ORB-SLAM3、VINS-Mono、A-LOAM、LeGO-LOAM、LIO-SAM、LVI-SAM、FAST-LIO2、FAST-LIVO、Faster-LIO、hdl_graph_slam。实验基于Ubuntu20.04,其中ORB、VINS-Mono、和LOAM系列的安装参考我以前的博客,有详细的安装方法,其他的框架在后面会简单介绍一下

zardforever123的博客 1万+

对象创建过程

这里说的对象创建过程,仅仅指的是普通的对象。创建对象,仅仅只是一个new关键字。 查找是否有符号引用:当虚拟机接收到一个new 指令时,会去常量池里面去找有没有这样到一个符号引用。 是否被加载:判断这个符号引用是否已经被加载链接初始化。如果没有,要先执行类的加载过程。 分配内存:分配内存的时候需要注意线程安全问题,为了避免同一块内存地址被分配给对象的问题。 主要有两种方式来避免 CAS...

ace423839506的专栏 250

别光看教程了!手把手带你用STM32F103C8T6最小系统板点亮第一个LED(附完整电路图)

本文详细介绍了如何使用STM32F103C8T6最小系统板点亮第一个LED,从硬件连接到软件开发环境搭建,再到编写和下载程序,手把手教你完成STM32入门的第一步。适合初学者快速上手STM32开发,附完整电路图和代码示例。

weixin_28678831的博客 193

第二章对象模型(3):从创建到销毁,对象的生命周期

1. 对象的创建 首先我们需要观察思考: Python 内部是如何从无到有创建一个浮点对象的 Python 又是怎么知道该如何将它打印到屏幕上的呢? >>> pi = 3.14 >>> print(pi) 3.14 下面以 floatl类型为例子,对应C实体是 PyFloat_Type 首先来介绍C API Python 是用 C 写成的,对外提供了 C API ,让用户可以从 C 环境中与其交互。 Python 内部也大量使用这些 API ,为了更好研

pythonstrat的博客 624

一步一步教你如何安装IP-Guard(客户端WINDOWS篇)

1、安装完服务器后,在服务器右下角有一个IP-GUARD图标:如图 2、点图标右键选注册: 3、注册成功后, 4、在开始菜单里选生成客户端安装包。 5、生成客户端安装包成功,安装名字可以任意,但是最好是英文名字。 6、将客户端安装程序复制到桌面。 7、退出所有杀毒软件、安全卫士、电脑管家等然后运行 8、安装完成后,立即重启计算机。IPguard客户端安装完成。 9、这样在控制里就可以看到已经安装客户端的计算机,在线显示蓝色,灰色表示计算机已经离线货关机 ...

IP-Guard专栏 5621

2025年“区块链技术”职业院校技能大赛赛后复盘与总结(必看)

记录一次2025年“区块链技术”职业院校技能大赛的参加经验总结与赛后复盘

我是网络安全兼技能大赛工程师,专注网络安全技术学习与技能大赛实战!持续分享最新的技术文章,帮你少走弯路,一起在技术赛道上进步~ 1990

《架构风清扬-Java面试系列第13讲》说一说Java对象在内存中的生命周期

像线程的生命周期,Servlet的生命周期,相信这类问题大家都非常熟悉了,今天我们来谈谈 Java对象在内存中的生命周期

架构风清扬 1573

Sigrity Power Tree如何进行直流压降仿真分析操作指导

Sigrity Power Tree模式可以用于前仿真,在没有layout文件的情况下对电源进行直流压降仿真分析,用于评估原理图设计以及器件选型是否合理。Model:设置为Equal Current,设置为等电源模型,意思该负载每个电源pin都是等电流的。Current:设置每个负载的电流,U30为3A,U3-U6各为1A。Nominal Current:设置能够承载的最大电流,设置为10A。Upper/ Lower Tol:设置为压降范围为5%Output Current:设置输出电流为10A。

weixin_54787054的博客 730

Java 内存分配、对象生命周期与垃圾回收

虚拟器规范中的7个内存区域分别是三个线程私有的和四个线程共享的内存区,线程私有的内存区域与线程具有相同的生命周期,它们分别是: 指令计数器、 线程栈和本地线程栈,共享区是所有线程共享的,在JVM启动时就会分配,分别是:方法区、 常量池、直接内存区和堆。 Java的内存回收必须解决两问题:那些对象需要回收、怎么回收。 回收判定算法,当前的大部分虚拟机采用的判定策略为:根搜索算法 回收算法:分代回收

悟已往之不谏,知来者之可追 971

复分析 阿尔福斯(Ahlfors) 第三版答案 英文

答案分为十章,有部分习题没有答案,全英文复分析阿尔福斯(Ahlfors) 第三版答案

ssm框架搭建

这个是一个在idea上成功跑起来的ssm框架项目,保存在这里方便以后使用直接下载

java对象的生命周期及回收

java对象的生命周期及回收   在网上看到一篇不错的文章,记录下来备忘。   要理解java对象的生命周期,我们需要要明白两个问题,    1、java是怎么分配内存的 ,2、java是怎么回收内存的。   喜欢java的人,往往因为它的内存自动管理机制,不喜欢java的人,往往也是因为它的内存自动管理。我属于前者,这几年的coding

jack 专栏 784

华为的C语言编程规范.pdf

华为技术有限公司内部技术规范。本规范制定了编写C语言程序的基本原则、规则和建议。从代码的清晰、简洁、可测试、安全、程序效率、可移植各个方面对C语言编程作出了具体指导。

Java内存分配(多实例演示)

目录 1 概述 2 内存区域分配 1、Java内存区域 2、内存分配 3、方法区中的常量池 3 内存分配机制 4 内存调用示意图 5 运行实例 实例1 实例2 实例 3 实例 4 1 概述 Java 程序运行时,需要在内存中分配空间。为了提高运算效率,就对空间进行了不同区域的划分,因为每一片区域都有特定的处理数据方式和内存管理方式。 一、栈:储存局部变量 局部变量:在方法的定义中或者在方法声明上的变量称为局部变量。 特点:栈内存的数据用完就释放。 二、堆:储存 new...

mocas_wang的博客 3738

OV9734 DATASHEET,完整规格书

OV9734完整规格书,包括电气参数,尺寸规格,寄存器配置表等

JVM-垃圾回收与内存分配

JVM-垃圾回收与内存分配

m0_50846237的博客 1749

java对象什么时候回收_java对象的生命周期

java对象的生命周期包括 创建、使用、回收 三个过程,本文将详细剖析每个过程。一、对象的创建当运行时执行代码遇到new指令、反序列化、反射、克隆时会创建新的对象。创建对象的过程如下图:对象创建过程中重要步骤的几点说明:分配内存:分配内存方式由两种,分别是指针碰撞和空闲列表。指针碰撞是指将内存划分为空闲的和用过的两块,这两块之间有一个指针作为分界点,当分配内存时将指针往空闲内存块移动。空闲列表是由...

weixin_34518801的博客 2089

JAVA对象生命周期

JAVA对象生命周期:http://shuaijie506.iteye.com/blog/1779651 在网上看到一篇不错的文章,记录下来备忘。   要理解java对象的生命周期,我们需要要明白两个问题,    1、java是怎么分配内存的 ,2、java是怎么回收内存的。   喜欢java的人,往往因为它的内存自动管理机制,不喜欢java的人,往往也是因为它的内存自动...

longxzq的专栏 123

JVM内存对象

类加载检查 虚拟机遇到一条new指令【new, 对象克隆,对象序列化等】,首先将去检查这个指令的参数是否能在常量池中定位到一个类的符号引用,并且检查这个符号引用代表的类是否已被加载过、解析和初始化过。如果没有进行类加载过程。 分配内存 JVM为新生对象分配内存。对象所需的空间在类加载后可确定,次步是将一块确定大小的内存从Java堆中划分出来。 划分算法 1. 指针碰撞(默认) 如果Java堆中...

Robin_812656252的博客 286

java内存结构

一、Java内存分配1、 Java有几种存储区域?* 寄存器     -- 在CPU内部,开发人员不能通过代码来控制寄存器的分配,由编译器来管理* 栈     -- 在Windows下, 栈是向低地址扩展的数据结构,是一块连续的内存的区域,即栈顶的地址和栈的最大容量是系统预先规定好的。     -- 优点:由系统自动分配,速度较快。     -- 缺点:不够灵活,但程序员是无法控制的。     -- 存放基本数据类型、开发过程中就创建的对象(而不是运行过程中)* 堆     -- 是向高地址扩展的数据结构,

Tony Chen的专栏 3883

疯狂JAVA16课之对象与内存控制

java内存管理分为两个方面:内存分配和内存回收。这里的内存分配特指创建java对象时JVM为该对象在对内存中所分配的内存空间。内存回收指的是当该java对象失去引用,变成垃圾时,JVM的垃圾回收机制自动清理该对象,并回收该对象所占用的内存。由于JVM内置了垃圾回收机制会收失去引用的java对象所占用的内存,所以很多java开发者认为java不存在内存泄漏,资源泄露的问题。实际上是一...

banghuangshuo6405的博客 100

深入理解Java虚拟机-第三章、垃圾收集器与内存分配策略

文章目录垃圾收集器与内存分配策略一、如何判断对象已经死了?1、引用计数器存在的问题:对象之间相互循环引用2、可达性分析算法GC Roots对象包含下面几种:3、引用分类强引用(不会被回收,如Object obj=new Object())软引用(用来描述一些还有用但并非必需的对象)弱引用虚引用4、不可达对象如何自救?5、方法区的回收三、垃圾回收算法1、标记清除算法标记清除算法的不足2、复制算法为什...

weixin_38367817的博客 286

深入解析JVM对象创建与内存分配机制

jdk1.6 update14开始,在64bit操作系统中,JVM支持指针压缩jvm配置参数:UseCompressedOops,compressed--压缩、oop(ordinary object pointer)--对象指针启用指针压缩:-XX:+UseCompressedOops(默认开启),禁止指针压缩:-XX:-UseCompressedOops。

qq_45061342的博客 1243

Java虚拟机垃圾回收(四) 总结: 内存分配与回收策略 方法区垃圾回收 以及 JVM垃圾回收的调优方法

Java虚拟机垃圾回收(四) 总结:内存分配与回收策略 方法区垃圾回收 以及 JVM垃圾回收的调优方法       在《Java对象在Java虚拟机中的创建过程》了解到对象创建的内存分配,在《Java内存区域 JVM运行时数据区》中了解到各数据区有些...

尚拙的博客 190

Java中堆内存与栈内存分配浅析

Java 把内存划分成两种:一种是栈内存,另一种是堆内存。在函数中定义的一些基本类型的变量和对象的引用变量都是在函数的栈内存中分配,当在一段代码块定义一个变量时,Java 就在栈中为这个变量分配内存空间,当超过变量的作用域后,Java 会自动释放掉为该变量分配的内存空间,该内存空间可以立即被另作它用。堆内存用来存放由 new 创建的对象和数组,在堆中分配的内存,由 Java 虚拟机的自动垃圾回收器来管理。在堆中产生了一个数组或者对象之后,还可以在栈中定义一个特殊的变量,让栈中的这个变量的取值等于数组或对象在

JasonChan2008的专栏 594
上一篇: 使用cygwin在windows下安装nodeJS
下一篇: mysql从同步管理
技术宝哥
博客等级 码龄16年 331粉丝 222原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值