Java虚拟机支持的最大内存限制

最近在开发Java的程序。本来我是一直很喜欢Java的内存管理的,不需要担心分配内存,只管分配,垃圾收集器自己会给你回收内存的。现在开发的程序数据量很大,为了速度快,我准备把所有的信息加载进内存,这样可以保证快速响应。我还在反复算内存,想想自己的数据量,现在刚开始的时候应该够了(我的机器是4G内存,虽然Windows就认3.5G,但是比起我现在的数据量应该没问题)。

  没想到第一个实验的程序,跑了几个小时,就遇到了Out of Memory Exception了。看看自己的虚拟机设置,我设置的是-Xms512M
-Xmx1024M。想都没想,直接改成-Xms512M -Xmx2048M,结果直接就Could not reserve enough space for
object heap。程序都起不来了。这才发现原来最大内存还有限制。上网搜了一下,发现很多讨论这个问题的文章。最终在BEA的DEV2DEV论坛发现了最有用的
一篇

  这里的版主YuLimin 做了测试,得出结论:

  公司
JVM版本                 
最大内存(兆)client    最大内存(兆)server

  SUN
1.5.x                         
1492                           
1520

  SUN
1.5.5(Linux)            
2634                           
2660

  SUN
1.4.2                         
1564                           
1564

  SUN
1.4.2(Linux)            
1900                           
1260

  IBM
1.4.2(Linux)            
2047                            
N/A

  BEA JRockit 1.5 (U3)     
1909                            
1902

  我现在用的是JDK1.6. 0_05,测试了一下。在Client状态下最大是,我的JDK不认-Server参数,测试不了Server状态。估计差不多。

  SUN
1.6.0                         
1442                          
N/a

  看样子用Java想用大内存也是不可能的了。而且一般的说法是内存太大了,垃圾收集的时间就会长。这也可以理解,一般是内存不够用了才收集的,扫描2G内存比1G当然要慢多了,而且内存对象多了,估计关系是指数上升的。

  下面附上YuLimin的测试方法和测试记录。

  测试方法:在命令行下用 java -XmxXXXXM -version
命令来进行测试,然后逐渐的增大XXXX的值,如果执行正常就表示指定的内存大小可用,否则会打印错误信息。

  • 堆(Heap)和非堆(Non-heap)内存
    按照官方的说法:“Java
    虚拟机具有一个堆,堆是运行时数据区域,所有类实例和数组的内存均从此处分配。堆是在 Java
    虚拟机启动时创建的。”“在JVM中堆之外的内存称为非堆内存(Non-heap
    memory)”。可以看出JVM主要管理两种类型的内存:堆和非堆。简单来说堆就是Java代码可及的内存,是留给开发人员使用的;非堆就是JVM留给
    自己用的,所以方法区、JVM内部处理或优化所需的内存(如JIT编译后的代码缓存)、每个类结构(如运行时常数池、字段和方法数据)以及方法和构造方法
    的代码都在非堆内存中。

  • 堆内存分配
    JVM初始分配的内存由-Xms指定,默认是物理内存的1/64;JVM最大分配的内存由
    -Xmx指定,默认是物理内存的1/4。默认空余堆内存小于40%时,JVM就会增大堆直到-Xmx的最大限制;空余堆内存大于70%时,JVM会减少堆
    直到-Xms的最小限制。因此服务器一般设置-Xms、-Xmx相等以避免在每次GC 后调整堆的大小。

  • 非堆内存分配
    JVM使用-XX:PermSize设置非堆内存初始值,默认是物理内存的1/64;由XX:MaxPermSize设置最大非堆内存的大小,默认是物理内存的1/4。

  • JVM内存限制(最大值)
    首先JVM内存限制于实际的最大物理内存(废话!呵呵),假设物理内存无限
    大的话,JVM内存的最大值跟操作系统有很大的关系。简单的说就32位处理器虽然可控内存空间有4GB,但是具体的操作系统会给一个限制,这个限制一般是
    2GB-3GB(一般来说Windows系统下为1.5G-2G,Linux系统下为2G-3G),而64bit以上的处理器就不会有限制了。

    所以说设置VM参数导致程序无法启动主要有以下几种原因:

    1) 参数中-Xms的值大于-Xmx,或者-XX:PermSize的值大于-XX:MaxPermSize;

    2)
    -Xmx的值和-XX:MaxPermSize的总和超过了JVM内存的最大限制,比如当前操作系统最大内存限制,或者实际的物理内存等等。说到实际物理
    内存这里需要说明一点的是,如果你的内存是1024MB,但实际系统中用到的并不可能是1024MB,因为有一部分被硬件占用了。

Java虚拟机支持的最大内存限制,码迷,mamicode.com

时间: 2024-10-02 08:46:48

Java虚拟机支持的最大内存限制的相关文章

Java虚拟机解析篇之---内存模型

今天闲来无事来,看一下Java中的内存模型和垃圾回收机制的原理.关于这个方面的知识,网上已经有非常多现成的资料能够供我们參考,可是知识还是比較杂的,在这部分知识点中有一本书不得不推荐:<深入理解Java虚拟机>,如今已经是第二版了.这本书就从头開始详细介绍了Java整个虚拟机的模型以及Java的类文件结构,载入机制等.这里大部分的知识点都是能够在这本书中找到的,当然我是主要还是借鉴这本书中的非常多内容的.以下就不多说了.进入主题吧. 首先来看一下Java中的内存模型图: 第一.程序计数器(PC

Java虚拟机结构及常见内存溢出异常

每个Java虚拟机都有一个类加载器子系统,根据某个全限定名来装入类型,同样每个Java虚拟机都有一个执行引擎,它负责执行那些包含在被装载类的方法中的指令. 当虚拟机运行一个程序时,就需要从已加载的文件中得到信息,将这些信息组织到运行时数据区,以便于管理. Java运行时的数据区域划分 1.程序计数器:程序计数器是一块较小的内存空间,可以看做是当前线程的字节码的行号指示器. Java虚拟机的多线程是通过线程轮流切换并分配处理器执行时间的方式来实现的,在任何一个时刻,一个处理器只会执行一条线程中的指

Java虚拟机垃圾收集器与内存分配策略

Java虚拟机垃圾收集器与内存分配策略 概述 那些内存需要回收,什么时候回收,如何回收是GC需要完成的3件事情. 程序计数器,虚拟机栈与本地方法栈这三个区域都是线程私有的,内存的分配与回收都具有确定性,内存随着方法结束或者线程结束就回收了. java堆与方法区在运行期才知道创建那些对象,这部分内存分配是动态的,本章笔记中分配与回收的内存指的就是:java堆与方法区. 判断对象已经死了 引用计数算法:给对象添加一个引用计数器,每当有一个地方引用它,计数器+1;引用失败,计数器-1.计数器为0则改判

深入理解java虚拟机读书笔记1--java内存区域

Java在执行Java程序的过程中会把它所管理的内存划分为若干个不同的数据区域.这些区域都有各自的用途.创建和销毁的时间,有一些是随虚拟机的启动而创建,随虚拟机的退出而销毁,有些则是与线程一一对应,随线程的开始和结束而创建和销毁. Java虚拟机所管理的内存将会包括以下几个运行时数据区域: 1 程序计数器 它是一块较小的内存空间,它的作用可以看做是当先线程所执行的字节码的信号指示器. java虚拟机的多线程是通过轮流切换并分配处理器执行时间的方式来实现的,在任何一个确定的时刻,一个处理器(对于多

深入理解java虚拟机-----&gt;垃圾收集器与内存分配策略(下)

1.  前言 内存分配与回收策略 JVM堆的结构分析(新生代.老年代.永久代) 对象优先在Eden分配 大对象直接进入老年代 长期存活的对象将进入老年代 动态对象年龄判定 空间分配担保  2.  垃圾收集器与内存分配策略 Java技术体系中所提倡的自动内存管理最终可以归结为自动化地解决两个问题: 给对象分配内存; 回收分配给对象的内存. 对象的内存分配,往大方向上讲就是在堆上的分配,对象主要分配在新生代的Eden区上.少数也可能分配在老年代,取决于哪一种垃圾收集器组合,还有虚拟机中的相关内存的参

Java虚拟机学习4、内存溢出

堆溢出 Java堆唯一的作用就是存储对象实例,只要保证不断创建对象并且对象不被回收,那么对象数量达到最大堆容量限制后就会产生内存溢出异常了.所以测试的时候把堆的大小固定住并且让堆不可扩展即可.测试代码如下 1 package com.xrq.test; 2 3 import java.util.ArrayList; 4 import java.util.List; 5 6 /** 7 * 测试内容:堆溢出 8 * 9 * 虚拟机参数:-Xms20M -Xmx20M -XX:+HeapDumpOn

JAVA虚拟机中的堆内存Heap与栈内存Stack

原文链接:http://www.cnblogs.com/laoyangHJ/archive/2011/08/17/gc-Stack.html 深入Java虚拟机:JVM中的Stack和Heap 在JVM中,内存分为两个部分,Stack(栈)和Heap(堆),这里,我们从JVM的内存管理原理的角度来认识Stack和Heap,并通过这些原理认清Java中静态方法和静态属性的问题. 一般,JVM的内存分为两部分:Stack和Heap. Stack(栈)是JVM的内存指令区.Stack管理很简单,pus

深入理解JAVA虚拟机 垃圾收集器和内存分配策略

引用计数算法 很多教科书判断对象是否存活的算法是这样的:给对象中添加一个引用计数器,每当有一个地方引用它时,计数器值就加1:当引用失效时,计数器值就减1:任何时刻计数器都为0的对象就是不可能再被使用的. 客观地说,引用计数算法(Reference Counting)的实现简单,判定效率也很高,在大部分情况下它都是一个不错的算法,也有一些比较著名的应用案例,例如微软的COM(Component Object Model)技术.使用ActionScript 3的FlashPlayer.Python语

Java虚拟机详解02----JVM内存结构

主要内容如下: JVM启动流程 JVM基本结构 内存模型 编译和解释运行的概念 一.JVM启动流程: JVM启动时,是由java命令/javaw命令来启动的. 二.JVM基本结构: JVM基本结构图: <深入理解Java虚拟机(第二版)>中的描述是下面这个样子的: Java中的内存分配: Java程序在运行时,需要在内存中的分配空间.为了提高运算效率,就对数据进行了不同空间的划分,因为每一片区域都有特定的处理数据方式和内存管理方式. 具体划分为如下5个内存空间:(非常重要) 栈:存放局部变量