首页 > 试题广场 >

你知道java里面的内存管理机制吗,比如创建和回收是怎么管理

[问答题]
你知道java里面的内存管理机制吗,比如创建和回收是怎么管理的?
jvm内存:栈,堆,方法区。栈是方法执行的内存模型,成员变量,方法的执行,局部变量,方法参数,就存在栈中,线程之间不共享。通过new关键字创建的对象都存在堆中,线程之间共享,方法区用于存静态变量,类代码信息,常量等,线程之间共享!
发表于 2019-04-30 22:34:54 回复(0)
更多回答
在java中,内存管理由JVM完全负责,java中的“垃圾回收器”负责自动回收无用对象占据的内存资源,这样可以大大减少程序猿在内存管理上花费的时间,可以更集中于业务逻辑和具体功能实现;但这并不是说java有了垃圾回收器程序猿就可以高枕无忧,将内存管理抛之脑外了!一方面,实际上java中还存在垃圾回收器没法回收以某种“特殊方式”分配的内存的情况(这种特殊方式我们将在下文中进行详细描述);另一方面,java的垃圾回收是不能保证一定发生的,除非JVM面临内存耗尽的情况。所以java中部分对象内存还是需要程序猿手动进行释放,合理地对部分对象进行管理可以减少内存占用与资源消耗。
发表于 2019-01-07 21:58:41 回复(0)

1)在Serial/Serial Old收集器下,对象优先在新生代Eden区中分配。当Eden去没有足够的空间进行分配时,虚拟机将发起一次Minor GC-XX:SurviorRatio=8,表示Eden:一个Survior=8:1,因此新生代总的可用空间为-Xmn的大小为Eden区和一个Survior的大小;

2)大对象直接进入老年代(eg:很长的字符串);    

3)长期存活的对象将进入老年代;

发表于 2019-03-23 22:31:52 回复(0)
jvm内存:栈,堆,方法区。栈是方法执行的内存模型,成员变量,方法的执行,局部变量,方法参数,就存在栈中,线程之间不共享。通过new关键字创建的对象都存在堆中,线程之间共享,方法区用于存静态变量,类代码信息,常量等,线程之间共享!
发表于 2019-01-29 13:16:12 回复(0)
创建管理:
    1. 大多数情况下,对象分配在Edgn区域。
    2. 大对象直接进入老年代区域。大对象指的是占用内存较大的对象,例如字符串数组。
    3. Eden区域长期存活的对象进入老年代。每一次MinorGc存活下来的对象年龄会加一并且从Edgn复制到Surivor区域。达到了阈值之后,进入老年代区域。-XX:MaxTenuringThreshold 用来定义年龄的阈值。
    4. 动态对象年龄判定。虚拟机不是要求所有的对象达到阈值之后才进入老年代。如果在 Survivor 中相同年龄所有对象大小的总和大于 Survivor 空间的一半,则年龄大于或等于该年龄的对象可以直接进入老年代,无需等到 MaxTenuringThreshold 中要求的年龄。
回收管理:
    1. 对于 Minor GC,其触发条件非常简单,当 Eden 空间满时,就将触发一次 Minor GC。
   而出发FullGc的条件比较复杂,主要有一下几条

1. 调用 System.gc()

只是建议虚拟机执行 Full GC,但是虚拟机不一定真正去执行。不建议使用这种方式,而是让虚拟机管理内存。

2. 老年代空间不足

老年代空间不足的常见场景为前文所讲的大对象直接进入老年代、长期存活的对象进入老年代等。

为了避免以上原因引起的 Full GC,应当尽量不要创建过大的对象以及数组。除此之外,可以通过 -Xmn 虚拟机参数调大新生代的大小,让对象尽量在新生代被回收掉,不进入老年代。还可以通过 -XX:MaxTenuringThreshold 调大对象进入老年代的年龄,让对象在新生代多存活一段时间。

3. 空间分配担保失败

使用复制算法的 Minor GC 需要老年代的内存空间作担保,如果担保失败会执行一次 Full GC。具体内容请参考上面的第 5 小节。

4. JDK 1.7 及以前的永久代空间不足

在 JDK 1.7 及以前,HotSpot 虚拟机中的方法区是用永久代实现的,永久代中存放的为一些 Class 的信息、常量、静态变量等数据。

当系统中要加载的类、反射的类和调用的方法较多时,永久代可能会被占满,在未配置为采用 CMS GC 的情况下也会执行 Full GC。如果经过 Full GC 仍然回收不了,那么虚拟机会抛出 java.lang.OutOfMemoryError。

为避免以上原因引起的 Full GC,可采用的方法为增大永久代空间或转为使用 CMS GC。

5. Concurrent Mode Failure

执行 CMS GC 的过程中同时有对象要放入老年代,而此时老年代空间不足(可能是 GC 过程中浮动垃圾过多导致暂时性的空间不足),便会报 Concurrent Mode Failure 错误,并触发 Full GC。


发表于 2020-08-14 09:57:35 回复(0)
JVM 负责 内管管理,内存主要划分为堆、栈、元数据空间,堆中主要存放实例对象和数组,可以划分为edge、from区、to区;栈存放对象是局部变量,操作数栈,引用,划分为一个个栈针;元数据空间主要存放对象是类信息,包括方法、静态变量、常量等,存储在直接存储空间中。
类创建是通过类加载器加载到内存;垃圾回收通过低优先级的守护进程 管理
发表于 2020-03-22 14:13:10 回复(0)
Ly~头像 Ly~
Java堆是Java虚拟机所管理的内存中最大的一块,在虚拟机启动时创建,此内存区域的目的就是存放对象实例,几乎所有的对象实例都在这里分配内存。从内存分配的角度来看,线程共享的Java堆中可能划分出多个线程私有的分配缓冲区(TLAB)。Java堆可以处于物理上不连续的内存空间,只要逻辑上连续即可,在实现上,既可以实现固定大小的,也可以是扩展的。如果堆中没有足够的内存分配给实例,并且堆也无法再拓展时,将会抛出OutOfMemeryError异常。
发表于 2019-05-05 23:59:01 回复(0)
java通过类加载器来加载class文件,加载到内存后,会把类、方法、常变量放到堆内存中。因为java是自动进行垃圾回收的,所以放入堆内存中的东西,哪些该回收,哪些不该回收?这都需要jvm去额外的线程去进行判断。但如果对于一个大型的J2EE系统来说,当创建的对象及方法变量比较多时,即堆内存中的对象比较多,如果一个一个对象去进行循环判断是否该回收时,这样的回收机制未免太耗时了,系统的性能一定会下降,jvm为了提高jvm执行效率,采用了堆内存分区管理的机制。
发表于 2019-05-04 22:10:15 回复(0)
新创建的对象进入eden区。经过多次gc后进去老年代
发表于 2019-01-17 08:04:20 回复(0)