假设你要观察JVM进程消耗的堆内存,通过命令工具jmap或可视化工具jvisualvm.exe。JVM这些参数的默认启动值。假设你想知道JVM内存分配策略,最开始手动设置这些参数。通过JDK统计结果,进行对照,就比較easy理解这些内存分配的理论知识。

执行环境是win7 32位操作系统,JDK1.7.0_60版本号。

測试代码和JVM启动參数例如以下:

public class Test
{
public static void main(String[] args)
{
int a = 0;
while (true)
{
a++;
}
}
}
-Xms=200M  -Xmx200M -XX:NewSize=100M -Xmn100M -XX:SurvivorRatio=8
-XX:OldSize=60M -XX:PermSize=50M -XX:MaxPermSize=50M

执行上述代码。通过jps命令获取到进程pid。然后通过jmap -heap pid就能够查看内存分配和使用情况。

>jmap -heap 8912
Attaching to process ID 8912, please wait...
Debugger attached successfully.
Client compiler detected.
JVM version is 24.60-b09 using thread-local object allocation.
Mark Sweep Compact GC Heap Configuration:
MinHeapFreeRatio = 40
MaxHeapFreeRatio = 70
MaxHeapSize = 209715200 (200.0MB)
NewSize = 104857600 (100.0MB)
MaxNewSize = 104857600 (100.0MB)
OldSize = 62914560 (60.0MB)
NewRatio = 3
SurvivorRatio = 8
PermSize = 52428800 (50.0MB)
MaxPermSize = 52428800 (50.0MB)

这里显示的堆配置參数。都能够通过JVM启动參数来设置。

以下来解释下几个重要參数的含义:

-Xms 和 -Xmx (-XX:InitialHeapSize 和 -XX:MaxHeapSize):指定JVM初始占用的堆内存和最大堆内存。JVM也是一个软件。也必需要获取本机的物理内

存,然后JVM会负责管理向操作系统申请到的内存资源。JVM启动的时候会向操作系统申请 -Xms 设置的内存。JVM启动后执行一段时间。假设发现内存空间

不足,会再次向操作系统申请内存。

JVM可以获取到的最大堆内存是-Xmx设置的值。

-XX:NewSize 和 -Xmn(-XX:MaxNewSize):指定JVM启动时分配的新生代内存和新生代最大内存。

-XX:SurvivorRatio:设置新生代中1个Eden区与1个Survivor区的大小比值。

在hotspot虚拟机中。新生代 = 1个Eden + 2个Survivor。假设新生代内存是

10M。SurvivorRatio=8,那么Eden区占8M,2个Survivor区各占1M。

-XX:NewRatio:指定老年代/新生代的堆内存比例。在hotspot虚拟机中,堆内存 = 新生代 + 老年代。

假设-XX:NewRatio=4表示年轻代与年老代所占比值为1:4,年轻代占整个堆内存的1/5。

在设置了-XX:MaxNewSize的情况下,-XX:NewRatio的值会被忽略,老年代的内存=堆内存
- 新生代内存。老年代的最大内存 = 堆内存 - 新生代 最大内存。

-XX:OldSize:设置JVM启动分配的老年代内存大小,类似于新生代内存的初始大小-XX:NewSize。

 -XX:PermSize 和 -XX:MaxPermSize:指定JVM中的永久代(方法区)的大小。

能够看到:永久代不属于堆内存,堆内存仅仅包括新生代和老年代

能够发现:堆内存、新生代内存、老年代内存、永久代内存,都有一个初始内存,另一个最大内存。

以下以老年代的初始内存和最大内存为例,看下内存变化的效果,其它的应该类似。測试代码例如以下:

public class TurnedTest
{
private static List<String> list = new ArrayList<String>(); public static void main(String[] args)
{
int a = 0;
while (true)
{
a++; list.add("demo");
} }
}

显然这个程序存在内存泄露。终于会占满整个堆内存,抛出OOM。为了看清楚这个演变的过程,我们在while循环中加入一个断点,设置breakpoint properties中的"hit count"为100000,以debug模式执行上面的程序。然后使用jmap观察内存占用情况。

   tenured generation:
capacity = 62914560 (60.0MB)
used = 0 (0.0MB)
free = 62914560 (60.0MB)
0.0% used tenured generation:
capacity = 62914560 (60.0MB)
used = 16409080 (15.648918151855469MB)
free = 46505480 (44.35108184814453MB)
26.08153025309245% used tenured generation:
capacity = 62914560 (60.0MB)
used = 53329496 (50.858970642089844MB)
free = 9585064 (9.141029357910156MB)
84.76495107014973% used tenured generation:
capacity = 104857600 (100.0MB)
used = 84217880 (80.3164291381836MB)
free = 20639720 (19.683570861816406MB)
80.3164291381836% used

能够发现老年代内存从最開始的60M,扩大到最大值100M。

版权声明:本文博客原创文章。博客,未经同意,不得转载。

(适合入门)JVM堆内存相关的启动参数:年轻一代、岁和永久代内存分配的更多相关文章

  1. JVM堆内存相关的启动参数:年轻代、老年代和永久代的内存分配

    如果想观察JVM进程占用的堆内存,可以通过命令工具jmap或者可视化工具jvisualvm.exe.JVM这些启动参数都拥有默认值,如果想了解JVM的内存分配策略,最好手动设置这些启动参数.再通过JD ...

  2. Storm程序永久代内存溢出

    在集群中部署Storm应用程序的时候报错,并通过jdk自带的jconsole监控发现,永久代内存瞬间爆炸了 org.springframework.beans.factory.BeanCreation ...

  3. JVM调优之Tomcat启动参数配置及详解

    开发项目中会遇到Tomcat内存溢出(java.lang.OutOfMemoryError: PermGen space)的问题,通过查找资料找到是通过设置Tomcat 启动堆空间大小.年轻代大小.每 ...

  4. JVM内存模型和启动参数的关系

    今天开始接触JVM的内存模型这一块的内容,以下这张图是从网上找的,先收藏了,虽然现在还看不太懂.以后弄懂了才进行详细的解说.

  5. jvm堆内存和GC简介

    最近经常遇到jvm内存问题,觉得还是有必要整理下jvm内存的相关逻辑,这里只描述jvm堆内存,对外内存暂不阐述. jvm内存简图 jvm内存分为堆内存和非堆内存,堆内存分为年轻代.老年代,非堆内存里只 ...

  6. linux启动参数了解

    文章来源:http://blog.csdn.net/uyiwfn/article/details/7172339在Linux中,给kernel传递参数以控制其行为总共有三种方法:1.build ker ...

  7. LINUX KERNEL启动参数

    LINUX KERNEL启动参数 在Linux中,给kernel传递参数以控制其行为总共有三种方法: 1.build kernel之时的各个configuration选项. 2.当kernel启动之时 ...

  8. linux内核可以接受的参数 | Linux kernel启动参数 | 通过grub给内核传递参数

    在Linux中,给kernel传递参数以控制其行为总共有三种方法: 1.build kernel之时的各个configuration选项. 2.当kernel启动之时,可以参数在kernel被GRUB ...

  9. 干货:JVM 堆内存和非堆内存

    堆和非堆内存 按照官方的说法:"Java 虚拟机具有一个堆(Heap),堆是运行时数据区域,所有类实例和数组的内存均从此处分配.堆是在 Java 虚拟机启动时创建的."" ...

随机推荐

  1. jsoncpp 不能处理long类型数据

    jsoncpp,是一个c++的解析和生成json的开源工具.假设你的c++程序须要解析或生成json,它会使这个过程变得非常easy! 可是,今天在用jsoncpp进行生成json的时候报了错误,非常 ...

  2. HDU 4893 Wow! Such Sequence!(2014年多校联合 第三场 G)(线段树)

    磨了一天的线段树,不能说完全搞清楚,只能说有一个大概的了解,靠着模板才把这道题A了,只能说太弱~~! 题意: 初始时有一字符串,全为0. 三种操作: 1 k d - add  把d加到第k个数上去2 ...

  3. iOS 使用UIBezierPath类实现随手画画板

    在上一篇文章中我介绍了 UIBezierPath类 介绍 ,下面这篇文章介绍一下如何通过这个类实现一个简单的随手画画板的简单程序demo,功能包括:划线(可以调整线条粗细,颜色),撤销笔画,回撤笔画, ...

  4. 开源力量公开课第三十期- 跟我一起玩转OpenStack

    开源力量公开课第三十期- 跟我一起玩转OpenStack 开课时间:2013年9月10日 18:30 - 21:30 形式:现场(北京3W咖啡) + 线上直播,   免费报名:http://www.o ...

  5. Socket 心跳包机制总结

    跳包之所以叫心跳包是因为:它像心跳一样每隔固定时间发一次,以此来告诉服务器,这个客户端还活着.事实上这是为了保持长连接,至于这个包的内容,是没有什么特别规定的,不过一般都是很小的包,或者只包含包头的一 ...

  6. Oracle中如何插入特殊字符:& 和 ' (多种解决方案)

    今天在导入一批数据到Oracle时,碰到了一个问题:Toad提示要给一个自定义变量AMP赋值,一开始我很纳闷,数据是一系列的Insert语句,怎么会有自定义变量呢?后来搜索了一下关键字AMP发现,原来 ...

  7. Android之后台服务判断本应用Activity是否处于栈顶

    在Android开发中,我们经常想知道是否自己的服务处于后台运行中,因为在后台运行的服务器优先级会降低,也就极有可能会被系统给回收掉,有什么好办法呢?Google推荐我们将服务运行到前台,如何知道服务 ...

  8. [读书笔记]设计原本[The Design of Design]

    第1章 设计之命题 1.设计首先诞生于脑海里,再慢慢逐步成形(实现) 2.好的设计具有概念完整性:统一.经济.清晰.优雅.利落.漂亮... 第2章 工程师怎样进行设计思维——理性模型 1.有序模型的有 ...

  9. Hibernate4读取Clob数据

    package cn.framework.dao.impl; import java.io.BufferedReader; import java.io.IOException; import jav ...

  10. Linux下select, poll和epoll IO模型的详解

    http://blog.csdn.net/tianmohust/article/details/6677985 一).Epoll 介绍 Epoll 可是当前在 Linux 下开发大规模并发网络程序的热 ...