JVM: 能不能在16G机器上设置17G的堆?

这是一个很有意思的问题:假设我们现在有一台物理内存16G的机器,那么我们能否给运行于其上的Java虚拟机分配大于16G大小的堆呢?

从直觉上来说,这似乎有点不太可能。但是稍微有点操作系统知识的人就会意识到,这其实是可以的。因为当我们设置堆大小为17G的时候,其实并不是直接分配了17G的物理内存。而只是分配了17G的虚拟内存。这些虚拟内存尚没有映射到真实的物理内存上。

为了验证这个结果,做一个小实验。

public class HelloWorld {
    public static void main(String[] args) {
        System.out.println("Hello, world");
    }
}

它会在我的Mac上运行,我的Mac物理内存16G:


很显然,我的机器已经占用了很多内存了,只剩下不多的东西。然后运行HelloWorld的main方法,设置参数:

-Xms17g -Xmx17g

将堆的大小固定为17G。
成功输出了结果:


现在我们进一步考虑这个问题,17G只是比16G大了一点点,也就是说,物理内存加上swap space,是大于17G的。如果我们将这个值设置得更加大,以至于堆大小比整个物理内存加上swap space还要大,会有什么情况呢?
设置参数

-Xms128g -Xmx128g

实际上,你可以将值设置得非常非常大,然后输出结果:

-Xms12800g -Xmx12800g

在这种设置下,依旧会输出"Hello World",但是中间有很长一段时间的卡顿,并且内存占用会一直上升,直到达到某个值:


为什么会是四十多G,这个问题我无法解释……因为我也不知道。
中间卡顿是因为操作系统分配虚拟内存。

那么又会有一个问题,堆究竟能设置到多大?
答案是,这取决于你的机器、操作系统和虚拟机。举例来说,在64位机器上运行32位的虚拟机,那么最大堆只能设置到4G——至少对于大多数的虚拟机来说4G就是上限了。

可以参考https://stackoverflow.com/questions/1434779/maximum-java-heap-size-of-a-32-bit-jvm-on-a-64-bit-os

理论上来说,虚拟机的堆大小只会受到虚拟内存地址空间大小的限制。

那么,什么时候操作系统才会真的分配物理内存给虚拟机呢?
答案就是,在内存第一次被使用的时候。这个使用并不是说我新建了一个对象,然后操作系统就唰的把所有物理内存分配好了,它只是按照虚拟机的需求,分配了一点点。(实际上是,只是把使用到的这部分内存按照页映射到了物理内存上)

虚拟机有一个参数可以控制整个过程,促使操作系统在虚拟机启动的时候就直接完成物理内存的绑定。使用参数:

-Xms128g -Xmx128g -XX:+AlwaysPreTouch

JVM直接就崩掉了:

Process finished with exit code 137 (interrupted by signal 9: SIGKILL)

实际上,在Linux上,只要加上整个-XX:+AlwaysPreTouch,操作系统就会在无法满足内存需求的时候直接kill掉JVM。最大值就是物理内存+swap大小-已经使用内存。

如果我真的将堆设置那么大,并且不使用-XX:+AlwaysPreTouch选项,那么JVM能够正常运行吗?
前面的HelloWorld其实很鸡贼,因为它真正运行所需的内存非常小。现在假设,我们的确需要一个128G大小的堆,但是我们的机器只有16G物理内存和16G swap space,那么在这台机器上运行虚拟机,它能正常工作吗?

答案是,它可能能够正常启动,但是肯定不能正常运行。因为虚拟机在启动的时候,并不是直接就使用了128G,只要启动时候所需要的内存不超过物理内存+swap space大小,就能启动。但是在运行的过程中,虚拟机不断的请求真的内存,那么就会超过32G,而后虚拟机就崩掉。这并不是OOM,而是在操作系统层面上的崩掉。

使用Swap space究竟好不好
答案是很糟糕,很不好。之前有一个小伙伴咨询过我一个GC停顿时间长的问题,就是因为swap space。在GC的时候,要沿着引用链查找所有的存活对象。如果这部分对象所在的内存被放到了swap space上,那么就会引起缺页中断。极端情况下,会出现不断置换页。一个页在开始的时候没被扫描到,交换到了swap space上,而后又被载入物理内存,因为立刻又扫描它了。

JVM使用了TLB的技术,所以其空间局部性还是很好的。

所以比较好的实践是,在Linux机器上将vm.swappiness参数设置到0,也就是不适用swap space。在使用大堆的情况下,这是一个非常隐蔽的坑。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 158,560评论 4 361
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,104评论 1 291
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,297评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,869评论 0 204
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,275评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,563评论 1 216
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,833评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,543评论 0 197
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,245评论 1 241
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,512评论 2 244
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,011评论 1 258
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,359评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,006评论 3 235
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,062评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,825评论 0 194
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,590评论 2 273
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,501评论 2 268

推荐阅读更多精彩内容