`

Java之内存模型之堆内存(Heap)

阅读更多
Java 内存模型之堆内存(Heap)


一、背景知识:内存类型介绍




1、什么是 Perm Gen?

Perm Gen : Permanent Generation

Perm Gen 区是一个特殊的JVM内存区,因为它用来存储用来描述 Class 的
元数据(Class 可以不属于Java语言的一部分,也可以属于),诸如:描述类及其方法。

在大的应用中该区一会儿就满了,并抛出错误:java.lang.OutOfMemoryError: PermGen
然而无论你怎么设置 -Xmx 也不管用。
因为设置其大小的参数不是 -Xmx,而是 -XX:PermGen, -XX:MaxPermGen (不同Java版本略有变化)


2、Heap VS. Stack VS. Perm

Heap(堆内存):
使用Java语言创建的所有的引用对象类型,都在此存储。并由 GC (Garbage Collection)对其进行管理,
诸如:释放不再被程序引用的对象所占据的内存。

Stack(栈内存):
与 Heap 相对的是,Stack 存放基础数据类型。诸如:int, char 等。
由程序的执行顺序控制变量的进出栈顺序,而不是由 GC 控制栈内存的管理。

Perm(持久内存):
用于存储类的元数据。诸如:类的定义,方法的定义等。

Perm 的生命周期与 JVM 绑定,而 Heap 的生命周期与程序绑定。



二、堆内存(Heap) 与 Garbage Collection

理解 GC (Garbage Collection),需要理解 Heap 。

JVM 的 Heap 堆内存在物理上被划分为两部分:Young Gen, Old Gen


1、 JVM 内存管理之:Young Gen

所有新创建的 Object 首先被放在 Young Generation 内存区。
如果 Young Generation 内存区满了,则执行 Garbage Collection 。这种 GC 称为 Minor GC。
Young Generation 区又分为三部分: Eden Memory,Survivor0 Memory (S0),Survivor1 Memory(S1).


Young Generation 内存区要点:

1、绝大多数新建的 Object 被放在 Eden Memory

2、如果 Eden Memory 内存满了,则进行 GC 操作。
   同时把未被 GC 的 Object 移动到 S0 或 S1 中。
   此时 Minor GC 也会检查和移动 S0 和 S1 中的对象。
   最后使 S0,S1 其中一个置为空。

3、多次 GC 后仍然未被 GC 的 Object 将被移动到 Old Gen 内存区中。
   通常 Object 会被 GC 设定一个轮询的阀值。


2、 JVM 内存管理之:Old Gen

Old Gen 内存区存放了经过多次 Minor GC 后仍然不能被 GC 的 Object。
与 Young Gen 相同,当 Old Gen 区满了之后将执行 GC 操作,该操作称为:Major GC。
耗用的时间也相对较长。

stop-the-world 事件
Young Gen 和 Old Gen 都可以主动触发 stop-the-world 事件,挂起所有任务,执行 GC 操作。
被挂起的任务只有在 GC 执行完毕后,才会恢复执行。
多数情况下, GC 性能调优(GC tuning)就是指降低 stop-the-world 时 GC 执行的时间。


三、Perm Gen

JVM 在 Permanent Generation 或 Perm Gen 内存区中存放应用程序的元数据
(application metadata),用来描述类及其方法的原始信息。
注意:Perm Gen 不是 Heap 的一部分。

Perm Gen 被 JVM 使用于应用程序运行期间(runtime),基于应用所使用到的类。
Perm Gen 中同时包括 Java SE 包中的类。
Perm Gen 只有在执行 Full GC 时才会被 GC。


四、内存管理调优参数

-Xms
设置JVM启动时的堆内存(Heap)的大小

-Xmx For setting the maximum heap size.
设置堆内存(Heap)的最大值

-Xmn
设置 Young Gen 内存区的大小

-XX:PermGen
设置 Perm Gen 内存的初始大小

-XX:MaxPermGen
设置 Perm Gen 内存的最大值

-XX:SurvivorRatio
设置 Eden Gen 与 S0 Gen,S1 Gen 内存的大小比。默认值:8
例如:
Young Gen 大小为 10M,
-XX:SurvivorRatio=2
则:
Eden Gen 的大小为 5,
S0 和 S1 的大小分别为 2.5
   
-XX:NewRatio
设置 Old Gen / Young Gen 的值。默认:2


大部分情况下,默认值不用调。详细请参考官方文档


五、Java内存管理之 Garbage Collection


垃圾回收 GC (Garbage Collection) 是 Java 鉴别、移出内存中不再使用的对象,
并释放其所占内存的过程。

Java 语言的一项非常好的特点就是:自动垃圾回收(Automatic GC)。
不像其它语言(例如 C 语言),需要手动释放内存。

Java 的垃圾收集器是一个在后台运行的程序,它检查所有在内存中运行的对象,
并找出那些不再在程序中的任何地方引用到的对象。
这些对象将被声明为程序运行垃圾,以释放其所占的内存,为其它对象继续使用。

GC 的运行步骤:

      1、Marking(标记):
          这是GC工作的第一步。鉴定出不再使用的对象,并对其进行标记。

      2、Normal Deletion(一般化删除):
          移除不使用的对象,并释放其所占空间。

      3、Deletion with Compacting(压缩删除):
          在删除所有不再使用的对象后,所有未被删除的对象将被移动到一起。
          这样可以提高对 new Objects 分配内存时的性能。


这种简单的 Mark 然后 delete 的方式有两点不足:

      1、不高效。新对象刚创建完,还没有被引用时就被删除了。
      2、重复。那些即使一直被程序引用的对象,也要在每次的GC轮询中被检查。








-
转载请注明,
原文出处:http://lixh1986.iteye.com/blog/2351465

















-
引用:
http://www.journaldev.com/2856/java-jvm-memory-model-memory-management-in-java
http://stackoverflow.com/a/4848711/2893073
http://www.cubrid.org/blog/dev-platform/understanding-java-garbage-collection




  • 大小: 27.1 KB
分享到:
评论

相关推荐

    深入Java内存分配

    Java有几种存储区域? java内存分配 Java内存模型 Java内存分配实例解析 String 常量池问题 堆(Heap)和非堆(Non-heap)内存 堆内存分配 非堆内存分配

    JVM入门实战/arthas实战/垃圾回收算法/垃圾回收器/jvm内存模型分析

    1.3 Heap堆内存模型 第三节:定位垃圾对象的依据 1.1 引用计数法 1.2 可达性算法 第四节:垃圾回收算法 1.1标记清除算法 1.2复制算法 1.3 标记整理(标记压缩)算法 第五节:垃圾回收器 1.1Serial/Serial Old...

    Java核心基础+Java中的数据在内存中的存储

    1、内存中的堆(stack)与栈(heap) 2、Java中数据在内存中的存储 基本数据类型的存储 对象的内存模型 ... Java内存分配中的堆 4、String.intern() 5、关于equasl()与== 6、关于String是不可变的

    java核心面试技术点

    java 内存模型 ( java memory model ):根据Java Language Specification中的说明, jvm系统中存在一个主内存(Main Memory或Java Heap Memory),Java中所有对象成员变量都储存在主存中,对于所有线程都是共享的。...

    java核心面试

    java 内存模型 ( java memory model ):根据Java Language Specification中的说明, jvm系统中存在一个主内存(Main Memory或Java Heap Memory),Java中所有对象成员变量都储存在主存中,对于所有线程都是共享的。...

    深入理解Java String#intern()内存模型

    大家知道,Java中string.intern()方法调用会先去字符串...下面,我们通过测试程序来窥探字符串常量池在Java6,Java7两个不同版本底下的内存分配情况。  测试程序 public class StringPoolTest { public void testSt

    Tomcat内存溢出的三种情况及解决办法分析

    有一点需要注意:java -Xmx***M version 命令来测试的最大堆内存是 -Xmx与 -XX:PermSize的 和 比如系统支持最大的jvm堆大小事1.5G,那 -Xmx1024m -XX:PermSize=768M 是无法运行的。 第三种:无法创建新的线程。 ...

    JVM规范--高手总结

    JVM内存模型 4 2.1 JVM规范 5 2.2 Sun JVM 8 2.3 SUN JVM内存管理(优化) 10 2.4 SUN JVM调优 13 2.5.JVM简单理解 16 2.5.1 Java栈 16 2.5.2 堆 16 2.5.3 堆栈分离的好处 20 2.5.4 堆(heap)和栈(stack) 20 JAVA垃圾...

    jvm相关1

    jvm内存逻辑模型栈、堆、方法区、程序计数器、本地方法区堆(heap):是java虚拟机所管理的内存中最大的一块内存区域,也是被各个线程共享的内存区域,该内存区

    java 面试题 总结

    内存处理是编程人员容易出现问题的地方,忘记或者错误的内存回收会导致程序或系统的不稳定甚至崩溃,Java提供的GC功能可以自动监测对象是否超过作用域从而达到自动回收内存的目的,Java语言没有提供释放已分配内存的...

    JavaSE基础面试题.docx

    11.Java中的内存模型 12.JVM如何调整内存大小 13.如何实现Java优化 14.各个集合在项目中的应用场景 15.对ArrayList扩容的理解 16.使用LinkedList删除元素的步骤 17.HashMap、Hashtable、ConcurrentHashMap底层实现...

    Java 虚拟机面试题全面解析(干货)

    什么是Java内存模型? Java内存模型的目标? 主内存与工作内存 内存间的交互操作 原子性、可见性、有序性 volatile 什么是 volatile? 为什么基于 volatile变量的运算在并发下不一定是安全的? 为什么使用 volatile? ...

    java面试题,180多页,绝对良心制作,欢迎点评,涵盖各种知识点,排版优美,阅读舒心

    【JVM】Java内存模型 44 【JVM】jvm内存模型 45 主内存与工作内存 45 内存间交互操作 46 重排序 48 【JVM】内存泄漏 49 【JVM】java虚拟机的区域如何划分,每一个区的动能? 49 程序计数器(Program Counter ...

    java面试宝典

    31、java 中会存在内存泄漏吗,请简单描述。 11 32、abstract 的method 是否可同时是static,是否可同时是native,是否可同时是synchronized? 11 33、静态变量和实例变量的区别? 11 34、是否可以从一个static 方法...

    超级有影响力霸气的Java面试题大全文档

    内存处理是编程人员容易出现问题的地方,忘记或者错误的内存回收会导致程序或系统的不稳定甚至崩溃,Java提供的GC功能可以自动监测对象是否超过作用域从而达到自动回收内存的目的,Java语言没有提供释放已分配内存的...

    java面试题

    答:运行时异常时(JVM)java虚拟机在运行过程中发生的问题,比如:内存溢出等问题。这类异常没法要求程序员去一一捕获并抛出,一般异常是Java类库或程序员自己写的代码发生的错误,这类异常可以由我们去一一捕获并...

    java核心知识点整理.pdf

    堆(Heap-线程共享)-运行时数据区 ...................................................................................... 23 2.2.5. 方法区/永久代(线程共享) ..................................................

    JAVA核心知识点整理(有效)

    2.2.4. 堆(Heap-线程共享)-运行时数据区 ...................................................................................... 23 2.2.5. 方法区/永久代(线程共享) ............................................

    千方百计笔试题大全

    31、java 中会存在内存泄漏吗,请简单描述。 11 32、abstract 的method 是否可同时是static,是否可同时是native,是否可同时是synchronized? 11 33、静态变量和实例变量的区别? 11 34、是否可以从一个static 方法...

    Linux多线程服务端编程:使用muduo C++网络库

    《Linux多线程服务端编程:使用muduo C++网络库》主要讲述采用现代C++在x86-64 Linux上编写多线程TCP网络服务程序的主流常规技术,重点讲解一种适应性较强的多线程服务器的编程模型,即one loop per thread。...

Global site tag (gtag.js) - Google Analytics