对于我的Java应用程序,我试图使用命令行选项来限制堆内存和直接使用内存。
当我试图了解更多关于VMware应用程序内存布局的信息时,我遇到了下面的文章。
从本文中,我假设可以使用-Xmx设置来限制堆的使用,而MaxDirectMemory设置可以用来限制堆之外的本机内存(图中的Guest内存)。但是,当我运行一个简单的程序时,结果是不同的。我使用ByteBuffer.allocateDirect分配本机内存,ByteBuffer.allocate分配堆内存。
它是一个64位处理器(OSX)和64位JVM。
第一实验
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
import java.nio.file.Paths;
import java.nio.file.Path;
import java.util.*;
public class javalimits {
public static void main (String [] args)
throws Exception {
ArrayList al = new ArrayList();
for(int i = 0; i< 100;i++) {
ByteBuffer bb = ByteBuffer.allocateDirect(1024 * 1024* 1024);
al.add(bb);
System.out.println(" Buffer loop "+ i);
Thread.sleep(500);
}
Thread.sleep(10000);
}
}当我在没有任何选项的情况下运行上面的程序时,它在3.6G内存分配之后崩溃了。当我使用"-XX:MaxDirectMemorySize=100g“选项或 "-Xms100g -Xmx100g”选项时,它在65循环或大约65G内存分配后崩溃。
我不明白
第二实验
我将ByteBuffer.allocateDirect改为ByteBuffer.allocate,用于在堆内存中而不是本机内存中分配。
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
import java.nio.file.Paths;
import java.nio.file.Path;
import java.util.*;
public class javalimits {
public static void main (String [] args)
throws Exception {
ArrayList al = new ArrayList();
for(int i = 0; i< 100;i++) {
ByteBuffer bb = ByteBuffer.allocate(1024 * 1024* 1024);
al.add(bb);
System.out.println(" Buffer loop "+ i);
Thread.sleep(500);
}
Thread.sleep(10000);
}
}当我在没有任何选项的情况下运行上面的程序时,它在2.7G内存分配之后崩溃了。当我使用"-XX:MaxDirectMemorySize=100g“选项时,它没有任何效果。它在2.7G内存分配后崩溃。我觉得这是有道理的。但是,当我添加"-Xms100g -Xmx100g“选项时,它在48个循环或大约48G内存分配后崩溃。
我不明白为什么,
第三实验
我在循环中启用了allocateDirect和分配函数。当我添加"-Xms100g -Xmx100g“选项时,它在24循环之后崩溃,或者将两者结合起来有效地分配48G内存。(本地内存24G +堆内存24g)
有人能帮我理解理解Java内存布局的错误吗?(参考链接中的图表)
发布于 2017-01-03 14:22:36
关于内存管理的很好的解释,您可以在这里找到:https://smarttechie.org/2016/08/15/understanding-the-java-memory-model-and-the-garbage-collection/
回答你的问题:
我不明白为什么,
物理内存不是系统的限制,它可以使用交换技术。这使系统能够从物理内存中删除很少被访问的修改页,从而使系统能够更有效地使用物理内存来处理更频繁访问的页。
48G的特别之处可能在于,您的系统能够只处理此数量的内存。你可以尝试玩沼泽和让系统分配所有100 G。
在从命令行运行java之前,请检查以下内容:
视窗
java -XX:+PrintFlagsFinal -version | findstr /i "HeapSize PermSize ThreadStackSize"Linux
java -XX:+PrintFlagsFinal -version | grep -iE 'HeapSize|PermSize|ThreadStackSize'此外,您还可以监视jconsol上的可视内存分配。
为什么会有不同大小的内存,您应该阅读以下内容:
https://stackoverflow.com/questions/41177462
复制相似问题