`
javaeyetodj
  • 浏览: 425937 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

Java内存的认识

    博客分类:
  • JVM
 
阅读更多

转自  http://blog.sina.com.cn/s/blog_68158ebf0100wp83.html

一、Java内存的构成

    先上一个官方java document里的图:
我对Java内存的认识(原创)
    由上图可知,整块区域分为Young Generation、Tenured Generation、Permanent Generation。
 
详细解释一下Young区:
    Young区又分为:Eden、Survivor Space。
    Survivor Space又分为 To Survivor、 From Survivor,如下图所示:
 
我对Java内存的认识(原创)

 
Java内存分为 堆内存(heap)和 Permanent区。
1、Java堆内存(heap):
    --是 JVM 用于分配 Java 对象的内存,包含活动对象和不可用对象 
    --堆大小通常是在服务器启动时使用 java 命令中的 –Xms(最小) –Xmx(最大)标志来定义。 
2、Permanent区:
    --指内存的永久保存区域
    --是Sun JDK和HP JDK用来加载类(class)和Meta信息的专门的内存区
    --这个区域不归属Java堆内存(heap)范围
    --Class在被Loader时就会被放到此,如果Java应用很大,例如类(class)很多,那么建议增大这个区域的大小来满足加载这些类的内存需求
    --通过–XX:PermSize=***M –XX:MaxPermSize=***M调整
 
这里还有一个本地内存的概念:
·本地内存(native memory): 
    --是 JVM 用于其内部操作的本地内存(非Java内存) 
    --JNI 代码和第三方本地模块(例如,本地 JDBC 驱动程序)也使用本地内存 
    --最大本地内存大小取决于以下因素:操作系统进程内存大小限制、已经指定用于 Java 堆的内存
 
也就是说,整个物理机的内存可以说由以下部分构成:
物理内存 = Java 内存 + 本地内存 + 操作系统保留的内存
 
 
二、垃圾回收(Garbage Collection,GC)
 
1、为什么要垃圾回收
    --JVM自动检测和释放不再使用的内存。 
    --Java 运行时JVM会执行 GC,这样程序员不再需要显式释放对象。 
 
2、垃圾回收(GC)的分类
    --Minor GC
    --Full GC
 
3、垃圾回收(GC)的产生过程
     1)新生成的对象在Eden区完成内存分配
     2)当Eden区满了,再创建对象,会因为申请不到空间,触发minorGC,进行young(eden+1survivor)区的垃圾回收。(为什么是eden+1survivor:两个survivor中始终有一个survivor是空的,空的那个被标记成To Survivor)
     3)minorGC时,Eden不能被回收的对象被放入到空的survivor(也就是放到To Survivor,同时Eden肯定会被清空),另一个survivor(From Survivor)里不能被GC回收的对象也会被放入这个survivor(To Survivor),始终保证一个survivor是空的。(MinorGC完成之后,To Survivor 和 From Survivor的标记互换)
     4)当做第3步的时候,如果发现存放对象的那个survivor满了,则这些对象被copy到old区,或者survivor区没有满,但是有些对象已经足够Old(通过XX:MaxTenuringThreshold参数来设置),也被放入Old区
     5)当Old区被放满的之后,进行完整的垃圾回收,即 Full GC
     6)Full GC时,整理的是Old Generation里的对象,把存活的对象放入到Permanent Generation里。
 
4、垃圾回收的回收器
  --串行(–XX:+UseSerialGC )
    Out of Box算法,年轻代串行复制,年老代串行标记整理,主要用于桌面应用
 
  --并行(–XX:+UseParallelGC )
     年轻代暂停应用程序,多个垃圾收集线程并行的复制收集,年老代暂停应用程序,与串行收集器一样,单垃圾收集线程标记整理。JDK 6.0启用该算法后,默认启用了-XX:+UseParallelOldGC,性能大为提高
 
  --并发(Concurrent Low Pause Collector)( –XX:+UseConcMarkSweepGC )
     启用该参数,默认启用了-XX:+UseParNewGC;简单的说,并发是指用户线程与垃圾收集线程并发,程序在继续运行,而垃圾收集程序运行于其他CPU上。
 
 
三、Java内存的调优参数
-Xmx1024m:
    设置JVM最大可用内存为1024M。
 
-Xms1024m:
    设置JVM促使内存为1024M。此值可以设置与-Xmx相同,以避免每次垃圾回收完成后JVM重新分配内存。
 
-Xmn512m:
    设置年轻代大小为512M。(持久代一般固定大小为64m,所以增大年轻代后,将会减小年老代大小。此值对系统性能影响较大,Sun官方推荐配置为整个堆的3/8。)
 
-Xss128k:
    设置每个线程的堆栈大小。这个值可以根据应用的线程所需内存大小进行调整。在相同物理内存下,减小这个值能生成更多的线程。但是操作系统对一个进程内的线程数还是有限制的,不能无限生成。
 
-XX:NewRatio=4
    设置年轻代(包括Eden和两个Survivor区)与年老代的比值(总的大小是Xms的值)。设置为4,则年轻代与年老代所占比值为1:4,年轻代占整个堆栈的1/5。
    举个例子,-Xms 设置为 1024m,-Xmx 也设置为 1024m的情况下:
      ·年轻代 = 1024M/5 = 204.8M
      ·年老代 = 1024M/5*4 = 819.2M
    如果-Xms和-Xmx的值设置的不一样,可以添加 -XX:MinHeapFreeRatio=<minimum> 和 -XX:MaxHeapFreeRatio=<maximum> 参数,使内存的大小能够在 大于 -Xms 和 小于 -Xmx 之间的范围内自动调整,所以内存中会有Virtual的空间(我是这样理解的,不是太清楚,这里需要大家指教)
    By default, the virtual machine grows or shrinks the heap at each collection to try to keep the proportion of free space to live objects at each collection within a specific range. This target range is set as a percentage by the parameters -XX:MinHeapFreeRatio=<minimum> and -XX:MaxHeapFreeRatio=<maximum>, and the total size is bounded below by -Xms and above by -Xmx .
 
-XX:SurvivorRatio=4:
    设置年轻代中Eden区与Survivor区的大小比值。设置为4,则两个Survivor区与一个Eden区的比值为2:4,一个Survivor区占整个年轻代的1/6
 
-XX:MaxPermSize=16m:
    设置持久代大小为16m。
 
-XX:MaxTenuringThreshold=0:
    设置垃圾最大年龄。如果设置为0的话,则年轻代对象不经过Survivor区,直接进入年老代。对于年老代比较多的应用,可以提高效率。如果将此值设置为一个较大值,则年轻代对象会在Survivor区进行多次复制,这样可以增加对象再年轻代的存活时间,增加在年轻代即被回收的概论。
 
总结如下图:
我对Java内存的认识(原创)
 
 
四、内存分配中会出现的错误
关于内存最常见的错误应该是这两个:
  -- 内存溢出 Out Of Memory(OOM)
  -- 内存泄露 Memory Leak (ML)
 
1、内存溢出
    内存溢出发生在这种状况下:Java内存完成Minor GC 之后想要把还存活的对象放到 Old区 里,但是这时Old区 已经满了,同时 Permanent区也已经放不下存活的对象。这时就会产生 OOM 错误。
 
2、内存泄露
    在Java中,内存泄漏就是存在一些被分配的对象,这些对象有下面两个特点,首先,这些对象是有被引用的,即在有向树形图中,存在树枝通路可以与其相连;其次,这些对象是无用的,即程序以后不会再使用这些对象。如果对象满足这两个条件,这些对象就可以判定为Java中的内存泄漏,这些对象不会被GC所回收,然而它却占用内存。
    找到一个例子:
    “这里引用一个常看到的例子,在下面的代码中,循环申请Object对象,并将所申请的对象放入一个Vector中,如果仅仅释放对象本身,但因为Vector仍然引用该对象,所以这个对象对GC来说是不可回收的。因此,如果对象加入到Vector后,还必须从Vector中删除,最简单的方法就是将Vector对象设置为null。

  1. Vector v = new Vector(10);      
  2. for (int i = 1; i < 100; i++)      
  3. {      
  4.  Object o = new Object();      
  5.  v.add(o);      
  6.  o = null;      
  7. }//此时,所有的Object对象都没有被释放,因为变量v引用这些对象。     

实际上这些对象已经是无用的,但还被引用,GC就无能为力了(事实上GC认为它还有用),这一点是导致内存泄漏最重要的原因。”

3、补充一个:PermGen space Error
    因为 GC 不会在主程序运行期对PermGen space进行清理,所以如果应用中有很CLASS需要Load的话,就很可能出现PermGen space错误。
    另外如果WEB APP下使用了大量的第三方jar, 其大小超过了 jvm 默认的大小那么也会产生此错误信息了。
 
 
五、总结
   上面4点的内容可以跟下面这个图来进行融合:
我对Java内存的认识(原创)
分享到:
评论

相关推荐

    深入理解 Java 内存模型_程晓明_InfoQ_java_内存模型_

    通过这个电子版,可以对JAVA的内存模型有一定的认识,使自己成为熟悉底层的高手

    Java内存泄漏

    Java系统内存泄漏的研究 让你轻松认识。java 中的内核机制及性能调优方面的东西。

    java内存管理详细介绍

    java内存管理详细介绍,增强自己对虚拟机和内存进一步认识!

    Java高并发实战_java高并发_高并发_

    介绍了两个重要的并行性能评估定律, 以及 Java 内存模型 JMM。第2章介绍了 Java 并行程序开发的基础, 包括 Java 中 Thread 的基本使用方法等第3章介绍了 JDK 内部对并行程序开发的支持, 主要介绍 JUC (Java.util....

    Java开发详解.zip

    031205_【第12章:JAVA IO】_内存操作流笔记.pdf 031206_【第12章:JAVA IO】_管道流笔记.pdf 031207_【第12章:JAVA IO】_打印流笔记.pdf 031208_【第12章:JAVA IO】_System类对IO的支持笔记.pdf 031209_【第12章...

    java 垃圾回收机制详细介绍

    里面关于垃圾收集器的内容也几乎没有,或者只是简单地提两句,所以很多参加Java Programmer认证考试的中国考生,在垃圾收集器这一部分的得分都为0分(笔者曾认识一位SUN公司授权的中国Java培训班的老师,其考试总分...

    java jdk8 学习笔记

    8.JVM让Java可以跨平台,不同的系统平台有不同的JVM,它们都认识.class文件。Java编译语言将Java代码编译成.class文件(只有一种形式),而C/C++语言将代码编译成01码,不同的操作系统的01码指令不同,这造成了不能跨...

    Java虚拟机规范(JavaSE7).pdf

    许多人知道类加载机制、JVM内存模型,但他们可能不知道什么是《Java虚拟机规范》。对于Java开发来说,《Java虚拟机规范》才是最为官方、准确的一个文档,了解这个规范可以让我们更深入地理解JVM。我们平常说的JVM...

    Java内存模型知识汇总

    本文中,有很多定义和说法,都是笔者自己理解后定义出来的。希望能够让读者可以对Java内存模型有更加清晰的认识。当然,如有偏颇,欢迎指正。

    Java虚拟机(JVM)面试题(总结最全面的面试题!!!)

    ) 文章目录Java内存模型我们开发人员编写的Java代码是怎么让电脑认识的为什么说java是跨平台语言Jdk和Jre和JVM的区别说一下 JVM由那些部分组成,运行流程是什么?说一下 JVM 运行时数据区详细的介绍下程序计数器?...

    jdk1.8的jvm内存模型——实习生必须了解的

    因为马上要准备实习面试了,而jvm又是面试常考的,我现在来总结一下jvm相关知识,而...这是大家所熟知的java内存模型,分为5个区域,下面说说我对他的认识: 1.程序计数器:首先它是线程私有的,是一个比较小的内存区

    Java常见面试问题整理.docx

    直接内存:不受JVM GC管理,直接内存并不是虚拟机运行时数据区的一部分,也不是Java 虚拟机规范中定义的内存区域。在JDK1.4 中新加入了NIO(New Input/Output)类,引入了一种基于通道(Channel)与缓冲区(Buffer)的I/...

    论文研究-移动应用程序内存泄露机制分析与检测方案设计.pdf

    Android开发已经成为移动开发热门领域,Android应用程序中内存使用的问题却经常容易被忽视,部分开发者对Java垃圾回收机制认识模糊,使得内存泄漏成为Android应用开发中十分隐秘但又确实存在的应用安全问题,对内存...

    JAVA面试题最全集

    对于java流的认识 28.简单描述一下awt与swing区别。 29.简述java编程中事件处理模式。 30.你编写过applet吗?applet的安全权限如何?试列举java application或者applet中与servlet/jsp通信可以采用的方式。 31...

    Java优化编程(第2版)

    15.1 用weakhashmap屏蔽内存泄漏 15.2 优化java应用大小 15.3 通过randomaccess接口优化迭代列表 15.4 合并java中的多进程与系统优化 小结 附录a together工具的使用简介 附录b j2se 5.0的新特性与性能的提升 附录c ...

    AIC的Java课程1-6章

     [*]了解Java内存机制:栈、堆、常量池等,理解垃圾回收机制。 第3章 面向过程(数组和方法) 4课时  理解如何声明数组、构造数组、初始化数组以及使用数组中的各个元素。  清楚数组作为...

    认识 java JVM虚拟机选项 Xms Xmx PermSize MaxPermSize 区别

    关于内存溢出报错的处理及解决方案: java.lang.OutOfMemoryError: PermGen space java.lang.OutOfMemory 堆内存、非堆内存都描述

    Java高并发编程详解:多线程与架构设计 (Java核心技术系列)

    内容简介 本书主要包含四个部分: ...volatile关键字在Java中非常重要,可以说它奠定了Java核心并发包的高效运行,在这一部分中,我们通过实例展示了如何使用volatile关键字以及非常详细地介绍了Java内存模型等知识

    JAVA8 面向对象编程免费视频

    一、类与对象 03001_面向对象简介 本课程主要讲解了面向对象与面向过程... 本课程主要讲解在Java中类的定义格式以及对象的产生格式,同时讲解了引用数据类型的内存分配与空指向问题的产生原因。 ....................

    Java性能优化解析

    在我们讨论怎样提高Java的性能之前,我们需要明白“性能“的真正含义。我们一般定义如下五个方面作为评判性能的标准。 1) 运算的性能----哪一个算法的执行性能最好 2) 内存的分配----程序需要分配多少内存,运行时...

Global site tag (gtag.js) - Google Analytics