很多人错误的认为运行Java程序时使用-Xmx和-Xms参数指定的就是程序将会占用的内存,但是这实际上只是Java堆对象将会占用的内存。堆只是影响Java程序占用内存数量的一个因素。要更好的理解你的Java程序将会占用多大的内存需要先了解有哪些因素会影响到内存的占用。这些因素包括:

  • 对象(Objects)
  • 类(Classes)
  • 线程(Theads)
  • 本地数据结构(Native data structures)
  • 本地代码(Native code)

每个因素对内存占用的影响又会随着应用程序、运行环境和系统平台的不同而变化,那怎样计算总的内存占用量?是的,想得到一个准确的数字不是那么容易,因为你很难控制本地(Native)部分。你能控制的部分只有堆大小:-Xmx,类占用的内存:-XX:MaxPermSize,还有线程栈:-Xss控制每个线程占用的内存。注意当把栈大小设置的太小时会导致StackOverflow异常、程序出错。所以,计算公式为:

(-Xmx) + (-XX:MaxPermSize) + 线程数 * (-Xss) + 其它内存

其它内存部分取决于本地代码占用的内存,如NIO、socket缓冲区、JNI等。它一般大约是jvm内存的5%左右。所以假设我们有下面的JVM参数和100个线程:

-Xmx1024m -XX:MaxPermSize=256m -Xss512k

那么jvm进程至少会占用内存数量为:1024m + 256m + 100*512k + (0.05 * 1330m) = 1396.5m

我一般使用(1.5 * 堆最大值)来作为一个近似值表示一个tomcat进程会需要的最小内存,如果你有需要增加MaxPermSize到256M以上的应用这个值可以更大些。如果你使用这个来衡量你的系统将会占用多少内存要记住你需要为系统和其它运行在系统上的程序留下足够的内存,否则会导致系统使用过多的虚拟内存,这样会降低性能。

不光是Java,任何依托在OS上执行的程序,OS所分配的内存都要大于程序内部自己申请的内存.很简单的道理,你不是一个人再战斗,程序的运行牵涉到方方面面,你写的代码只是其中的一个环节.托管语言更不可控.

我觉得Java把主要精力放到堆上是和它的gc相关,与线程相关的内存生命周期短。可能和主题不相干,看完之后想到的,就回复了。

空间换时间 。

如果内存很小的话 你看看JIT 还能不能那么强大 当然 是JIT可以跑起来的环境 但是内存小。

就是说除了程序所占用的内存,还有一个虚拟机在消耗内存。

Java所编写的程序在运行的时候占用内存是否真的很大了?“java程序运行的时候占用内存很大”我相信只要接触IT这个行业的人大部分的人都会毫不犹豫回答java程序运行的时候占用内存很大。也是许多java程序员默认的说法。在这里在这里我想在这里说下。

和许多程序员一样我也从c转到java的。由于c是公认的最接近机器语言的,而大部分程序员都会c语言。所以这里我用c与java进行测试比较结果。测试环境:计算机:P4,CPU:2.1GHz;内存:2G;jdk:1.7

测试:为了让效果精确,我特意让c和java两个程序所实现的功能语句尽量相同,在所写的行数上也力求一致。除此之外最重要的是让程序能裸奔。好啦,我相信大家和我一样迫不及待了吧,现在让我们来开始测试:

java:

public class JavaTest{

public static void main(String[] args){

for(int i=1;i<100000;i++){

for(int j=1;j<100000;j++){

}

}

}

}

现在我们在CMD中键入:java JavaTest<回车>,然后打开“任务管理器”可以看到这个程序占用内存“4910K”,也许大家看到这里还是觉得它占用内存很大。不要急的,我们再在CMD中键入:java @##@¥<回车>,这个是故意输错参数的,应为这个是java.exe本身运行的时候占用的内存,这个时候我们在看“任务管理器”显示进程占用内存为“4371K”。

那么这个程序到底占用内存多少了?4910K-4371K=539K.

好啦,我们现在来看看c程序运行的结果:

c:

int main (int argc,char* argv[])

{

for(int i=1;i<100000;i++){

for(int j=1;j<100000;j++){

}

}

return 0;

}

我们用vc++6.0编译运行,同样查看“任务管理器”程序占用内存情况。

可以看出内存为“675K”.

测试结果:总体来看,java进程“4910K”的确比c进程的“675K”多占用几倍内存。但是如果除去java本身所占用的内存,那么,这个java进程所占用内存实际占用比c进程占用内存还小,哈哈。。可能说道这里大家都不相信,呵呵。。。可是这是事实,大家如果不相信可以亲自测试下,那么大家可能要问那么java本身的占用内存那么大为什么啊?呵呵。。。只要大家看看sun公司开发java语言的目标和优点,就知道为什么啦,这个介绍就不具体时候了,网上有许多解释的文章,大家有需要可以上网了解一下。在这里另外说明一点的就是c能做的事情java也能做到,并且能很快做到,做的很好。除了很底层的事情:驱动、原始套接字(相信以后sun会提供)、系统级的程序(谁让系统是用c开发的了)。以后大家在看见有人说java占的内存多就可以辩论下了!同时也可以让大家明白凡事要自己求证,尤其作为程序员!

java占用大,是因为jvm、gc机制和oop造成的。

你这个简单的循环打印,因为有常量池的存在所以内存占用不明显,这是jvm对于自我的优化。

c++的很多方面都由自己手动和编译器控制,所以一个优秀的程序员和一个优秀的c++编译器同样重要。

而java把这方面更多的交由jvm控制,释放了程序员的压力,降低了程序员的门槛。

----------------------------------------------------------------------------------------------------

这个测试实例,是最简单的100000*100000次的循环,这个里面没有涉及到人工的任何优化,虽然jvm和c++编译器都会进行优化,对于这个内部优化谁的说不清楚在某种情况下谁优化的更好,现在很多的高级语言,很多都是基于c做起来的,所以暂时假设两种优化效果一样!很多客观的原因不能考虑一样,但是我们尽量做到一样、、、哈、、、这个也是做一定的探索、、、

---------------------------------------------------------------------------

在这里另外说明一点的就是c能做的事情java也能做到,并且能很快做到,做的很好。除了很底层的事情:驱动、原始套接字(相信以后sun会提供)、系统级的程序(谁让系统是用c开发的了)。这叫C能做的事情Java都可以做?那C可以写JVM.Java能写JVM么?就是因为Java干不了C的活所以才用C来做。另外内存占用C是可以调整的在PE结构里面就可以修改。Java可以修改么?单纯循环。vc连接器里面可以指定输出的可执行文件默认内存。最小可以优化到1k。非要比这个那就比吧讨厌那些Javaer总是自以为是的认为Java无敌的思想。如果你想要承认自己无敌你就要做出一些让别人信服的。C内存占用大那是系统分配给他就这么大。堆栈本身就需要占用。这个是可以优化掉的。JVM你可以优化掉么?优化掉Java怎么执行?所以被自欺欺人了。Java本来就以牺牲运行性能和内存为代价来模拟跨平台的。没人说错了。开发效率挺高的。这点牺牲也很值得。

为什么Java程序占用的内存比实际分配给它的要多的更多相关文章

  1. Java程序占用的内存可能会大于Xmx

    很多人认为Xmx和-Xms参数指定的就是Java程序将会占用的内存,但是这实际上只是Java堆对象将会占用的内存.堆只是影响Java程序占用内存数量的一个因素. 除了堆,影响Java程序所占用内存的因 ...

  2. Java程序占用实际内存大小

    很多人错误的认为运行Java程序时使用-Xmx和-Xms参数指定的就是程序将会占用的内存,但是这实际上只是Java堆对象将会占用的内存.堆只是影响Java程序占用内存数量的一个因素.要更好的理解你的J ...

  3. java程序运行时内存分配详解

    java程序运行时内存分配详解 这篇文章主要介绍了java程序运行时内存分配详解 ,需要的朋友可以参考下   一. 基本概念 每运行一个java程序会产生一个java进程,每个java进程可能包含一个 ...

  4. c/C++编译的程序占用的内存分为以下几个部分

    首先要搞清楚编译程序占用的内存的分区形式:一.预备知识—程序的内存分配一个由c/C++编译的程序占用的内存分为以下几个部分1.栈区(stack)—由编译器自动分配释放,存放函数的参数值,局部变量的值等 ...

  5. Java程序运行时内存划分

    1.Java程序跨平台运行的原因 主要原因是:各种平台的JVM和字节码文件 Java源程序--具体平台的机器代码文件---被编译器翻译成平台无关的Class文件,又用特定JVM运行字节码文件,JVM在 ...

  6. linux下分析java程序占用CPU、内存过高

    一.CPU过高分析 1)使用TOP命令查看CPU.内存使用状态可以发现CPU占用主要分为两部分,一部分为系统内核空间占用CPU百分比,一部分为用户空间占用CPU百分比.其中CPU状态中标示id的为空闲 ...

  7. java程序运行时内存分配详解 (转)

    转自:http://www.tuicool.com/articles/uU77v2 一.  基本概念 每运行一个java程序会产生一个java进程,每个java进程可能包含一个或者多个线程,每一个Ja ...

  8. windows下揪出java程序占用cpu很高的线程 并找到问题代码 死循环线程代码

    我的一个java程序偶尔会出现cpu占用很高的情况 一直不知道什么原因 今天终于抽时间解决了 系统是win2003 jvisualvm 和 jconsole貌似都只能看到总共占用的cpu 看不到每个线 ...

  9. 如何获知PHP程序占用多少内存(复制)

    想要知道编写的 PHP 脚本需要占用多少内存么?很简单,直接使用 PHP 查看当前分配给 PHP 脚本的内存的函数 memory_get_usage() 就可以了 下面是使用示例: 复制代码 代码如下 ...

随机推荐

  1. ES查询index对应的mapping信息

    private void getMappingByIndex(String indices) throws IOException { GetMappingsRequest getMappingsRe ...

  2. (转)JAVA正则表达式语法大全

    [正则表达式]文本框输入内容控制 整数或者小数:^[0-9]+\.{0,1}[0-9]{0,2}$ 只能输入数字:"^[0-9]*$". 只能输入n位的数字:"^\d{n ...

  3. 将安防IPC摄像机进行类似于萤石/乐橙/360水滴模式的互联网直播的几种方案

    前言 在维护EasyDarwin开源项目的几年内,几乎市面上大大小小的技术需求都给接触了一遍,大团队.大背景有大需求,草根团队有草根团队的需求,然而这些需求近些年都有一个发展的趋势,那就是" ...

  4. I.MX6 修改调试串口号(ttymx0 -> ttymxc2)

    I.MX6 修改调试串口号(ttymx0 -> ttymxc2) 一.参考文章: uboot修改默认调试串口ttymxc0 ->ttymxc4(imx53) http://www.xueb ...

  5. Sublime Text 2 设置文件详解(转)

    Sublime Text 2是那种让人会一眼就爱上的编辑器,不仅GUI让人眼前一亮,功能更是没的说,拓展性目前来说也完全够用了,网上介绍软件的文章和推荐插件的文章也不少,而且很不错,大家可以去找找自己 ...

  6. CODEVS3013 单词背诵 【Hash】【MAP】

    CODEVS3013 单词背诵 题目描述 Description 灵梦有n个单词想要背,但她想通过一篇文章中的一段来记住这些单词. 文章由m个单词构成,她想在文章中找出连续的一段,其中包含最多的她想要 ...

  7. HDU2222 Keywords Search 【AC自动机】

    HDU2222 Keywords Search Problem Description In the modern time, Search engine came into the life of ...

  8. RSA 每次公钥加密不同结果

    今天服务器端一哥们突然跑过来跟我说:我发现公钥每次加密都不同结果啊? 我说:怎么可能?不同的话,私要怎么解密和验证啊? 然后我屁颠屁颠的试了下,结果发现不论在在线RSA的还是自己公司 利用同一个明文加 ...

  9. nginx ngscript 简单使用

    备注: 默认没有集成到nginx包里,需要单独安装(推荐使用动态模块的方式进行安装) 1. 安装 wget https://nginx.org/download/nginx-1.13.11.tar.g ...

  10. yugabyte cloud native db 基本试用

    备注: 测试环境使用docker进行安装试用 1. 安装 a. Download mkdir ~/yugabyte && cd ~/yugabyte wget https://down ...