首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >为Java应用程序设置MaxDirectMemory和MaxHeapMemory

为Java应用程序设置MaxDirectMemory和MaxHeapMemory
EN

Stack Overflow用户
提问于 2016-12-16 04:51:08
回答 1查看 4K关注 0票数 8

对于我的Java应用程序,我试图使用命令行选项来限制堆内存和直接使用内存。

当我试图了解更多关于VMware应用程序内存布局的信息时,我遇到了下面的文章

从本文中,我假设可以使用-Xmx设置来限制堆的使用,而MaxDirectMemory设置可以用来限制堆之外的本机内存(图中的Guest内存)。但是,当我运行一个简单的程序时,结果是不同的。我使用ByteBuffer.allocateDirect分配本机内存,ByteBuffer.allocate分配堆内存。

它是一个64位处理器(OSX)和64位JVM。

第一实验

代码语言:javascript
复制
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内存分配后崩溃。

我不明白

  1. 既然我的物理内存只有16G,为什么它没有在内存分配16G之后崩溃呢?64G的本地内存分配有什么特别之处?
  2. 当我使用"-Xms100g -Xmx100g“时,本机内存分配限制是如何改变的?我假设本机内存限制仅由我提供的链接中的“-XX:MaxDirectMemorySize=100g”选项控制。但是,结果是不同的。内存大小设置也改变了直接内存缓冲区限制。
  3. 在没有提供命令行选项的情况下,3.6G内存分配有什么特殊之处?

第二实验

我将ByteBuffer.allocateDirect改为ByteBuffer.allocate,用于在堆内存中而不是本机内存中分配。

代码语言:javascript
复制
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内存分配后崩溃。

我不明白为什么,

  1. 既然我的物理内存只有16G,为什么它没有在内存分配16G之后崩溃呢?堆内存分配的48G有什么特别之处?
  2. 在没有提供命令行选项的情况下,2.7G内存分配有什么特殊之处?

第三实验

我在循环中启用了allocateDirect和分配函数。当我添加"-Xms100g -Xmx100g“选项时,它在24循环之后崩溃,或者将两者结合起来有效地分配48G内存。(本地内存24G +堆内存24g)

有人能帮我理解理解Java内存布局的错误吗?(参考链接中的图表)

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2017-01-03 14:22:36

关于内存管理的很好的解释,您可以在这里找到:https://smarttechie.org/2016/08/15/understanding-the-java-memory-model-and-the-garbage-collection/

回答你的问题:

我不明白为什么,

  1. 既然我的物理内存只有16G,为什么它没有在内存分配16G之后崩溃呢?堆内存分配的48G有什么特别之处?

物理内存不是系统的限制,它可以使用交换技术。这使系统能够从物理内存中删除很少被访问的修改页,从而使系统能够更有效地使用物理内存来处理更频繁访问的页。

48G的特别之处可能在于,您的系统能够只处理此数量的内存。你可以尝试玩沼泽和让系统分配所有100 G。

  1. 在没有提供命令行选项的情况下,2.7G内存分配有什么特殊之处?

在从命令行运行java之前,请检查以下内容:

视窗

代码语言:javascript
复制
java -XX:+PrintFlagsFinal -version | findstr /i "HeapSize PermSize ThreadStackSize"

Linux

代码语言:javascript
复制
java -XX:+PrintFlagsFinal -version | grep -iE 'HeapSize|PermSize|ThreadStackSize'

此外,您还可以监视jconsol上的可视内存分配。

为什么会有不同大小的内存,您应该阅读以下内容:

ByteBuffer.allocate()与ByteBuffer.allocateDirect()

票数 6
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/41177462

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档