一、Java内存的构成

先上一个官方java

document里的图:

由上图可知,整块区域分为Young

Generation、Tenured Generation、Permanent Generation。

详细解释一下Young区:

Young区又分为:Eden、Survivor

Space。

Survivor Space又分为 To

Survivor、 From Survivor,如下图所示:

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= 和

-XX:MaxHeapFreeRatio=

参数,使内存的大小能够在 大于 -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= and

-XX:MaxHeapFreeRatio=, 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区进行多次复制,这样可以增加对象再年轻代的存活时间,增加在年轻代即被回收的概论。

总结如下图:

四、内存分配中会出现的错误

关于内存最常见的错误应该是这两个:

--

内存溢出 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。

Vector v =newVector(10);

for(inti =1; i <100; i++)

{

Object o =newObject();

v.add(o);

o =null;

}//此时,所有的Object对象都没有被释放,因为变量v引用这些对象。

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

3、补充一个:PermGen space Error

因为 GC

不会在主程序运行期对PermGen space进行清理,所以如果应用中有很CLASS需要Load的话,就很可能出现PermGen

space错误。

另外如果WEB

APP下使用了大量的第三方jar, 其大小超过了 jvm 默认的大小那么也会产生此错误信息了。

五、总结

上面4点的内容可以跟下面这个图来进行融合:

perment java_我对Java内存的认识(原创)相关推荐

  1. volite java_同步和Java内存模型(五)Volatile

    作者:Doug lea 译者:杜建雄校对者:方腾飞 Volatile 从原子性,可见性和有序性的角度分析,声明为volatile字段的作用相当于一个类通过get/set同步方法保护普通字段,如下: f ...

  2. 字符串 压缩 java_简单的java字符串压缩(原创)

    复制内容到剪贴板 代码:package org.test;/** * 面试题目:现有一个字符串,其内容仅仅包含a---z,现在要进行网络传输,故需要减少网络传输的 * 大小,如何将字符串空间缩小.以下 ...

  3. 从底层吃透java内存模型(JMM)、volatile、CAS

    前言 随着计算机的飞速发展,cpu从单核到四核,八核.在2020年中国网民数预计将达到11亿人.这些数据都意味着,作为一名java程序员,必须要掌握多线程开发,谈及多线程,绕不开的是对JMM(Java ...

  4. Java内存溢出详解之Tomcat配置

    Java内存溢出详解 转自:http://elf8848.iteye.com/blog/378805 一.常见的Java内存溢出有以下三种: 1. java.lang.OutOfMemoryError ...

  5. 32位jdk最大内存_你了解Java 内存区域和GC机制吗?

    目录 Java垃圾回收概况 Java内存区域 Java对象的访问方式 Java内存分配机制 Java GC机制 垃圾收集器 Java垃圾回收概况 Java GC(Garbage Collection, ...

  6. 循序渐进:带你理解什么是Java内存模型

    近期笔者在阅读<深入理解Java虚拟机:JVM高级特性与最佳实现(第3版)>,书中提到关于Java内存模型的知识点,但是看完之后还是感觉有些模糊,便查阅一些其他相关资料.本文是笔者经过对知 ...

  7. java并发编程实战:第十六章----Java内存模型

    一.什么是内存模型,为什么要使用它 如果缺少同步,那么将会有许多因素使得线程无法立即甚至永远看到一个线程的操作结果 编译器把变量保存在本地寄存器而不是内存中 编译器中生成的指令顺序,可以与源代码中的顺 ...

  8. 好理解的Java内存虚假共享(False Sharing)性能损耗以及解决方案

    虚假共享(False Sharing)也有人翻译为伪共享 参考 https://en.wikipedia.org/wiki/False_sharing 在计算机科学中,虚假共享是一种性能降低的使用模式 ...

  9. JSR 133 Java内存模型以及并发编程的最权威论文汇总

    Java内存模型 先看官方文档: https://docs.oracle.com/javase/specs/ JSR 133:Java TM内存模型和线程规范修订版:https://www.jcp.o ...

  10. java线程的优先级是数字越大优先级越高_《深入理解Java虚拟机》5分钟速成:12章(Java内存模型与线程)...

    第12章 Java内存模型与线程 前言: 1.物理机如何处理并发问题? 2.什么是Java内存模型? 3.原子性.可见性.有序性的具体含义和应用实现? 4.volatile 关键字特性? 5.基于vo ...

最新文章

  1. Hbase基础(特点、架构、应用场景、集群搭建、HA设计)这一篇就够了
  2. C语言易错题集 第二部
  3. Q78:规则网格(Regular Grids)——Ray Tracing中的一种加速技术
  4. dmg2iso使用及转换DMG文件遇到的问题
  5. windows系统维护工具箱
  6. 冒泡排序程序java_冒泡排序Java程序
  7. qt 两界面类操作另外一个界面的的ui控件;以及会出现的the class containing “ui::XXX”cound not be found...Please verify the .
  8. 台式计算机操作系统的安装,台式电脑重装系统步骤图解
  9. 如何清除谷歌浏览器中的counterflix广告病毒
  10. iOS小技能:提取数字(文本框对粘贴内容进行手机号码提取)
  11. CentOS7中怎样设置静态IP
  12. Qt5设置应用程序图标
  13. gitlab centos 安装配置运维笔记
  14. 免费复制/下载收费文档的方法总结
  15. Python实现一个简单课堂点名器
  16. 探索未来|一文看懂小米年度技术峰会·硬件专场
  17. php无限循环分类,php实现无限分类功能
  18. 阿里云服务器带宽下载上传速度表(1Mbps是128KB/s)
  19. xctf攻防世界Leaking wp
  20. 【LeetCode系列】1185. 一周中的第几天

热门文章

  1. Spring Boot 中使用WebJars引入javasript依赖
  2. Halcon和Opencv区别
  3. 论文笔记_RSS_2014_激光SLAM_LOAM_实时LIDAR定位与建图
  4. 两幅图的RGB+Depth点云拼接
  5. HDU-2030-汉字统计
  6. [论文评析] ArXiv-2021,Pyramid Vision Transformer A Versatile Backbone for Dense Prediction without Convo
  7. .NET、ASP.NET控件及源码大汇总 最新最全哦
  8. 请假系统特例规则详细设计
  9. 关于信息安全工作方法论的一点猜想
  10. 苹果iOS苹果公司的手机用户都有权索赔