限制java应用程序的内存和cpu使用
Posted
技术标签:
【中文标题】限制java应用程序的内存和cpu使用【英文标题】:Limiting java application's memory and cpu usage 【发布时间】:2011-06-24 13:31:41 【问题描述】:说,“以 cpu=800 和 memory=1024 运行 myApp.jar”
我从事java编程多年,问这个问题很尴尬。我什至不知道这是否可能。如果有,怎么做?
我只想知道是否可以设置 java 程序的最大内存和 cpu 使用率。我突然想到这个,因为我最近开始开发移动应用程序。我想知道应用程序在内存和处理器非常有限的设备上的行为。
我看到带有演示应用程序的物理引擎可以在浏览器上运行,或者我可以在我的 PC 上执行。如果我在移动设备上运行它们会怎样?性能会一样吗?与其开发一个示例移动应用程序来测试库的性能,我宁愿先在我的 PC 上使用特定的 CPU 和内存运行它。
顺便说一句,我尝试用谷歌搜索...我发现的只是监控和性能调整。我可能使用了错误的关键字。
【问题讨论】:
【参考方案1】:您可以通过 -Xmx 选项限制内存使用,并且可以通过设置进程的优先级和/或 CPU 亲和性来限制 CPU 使用。
【讨论】:
在linux上,你可以使用taskset(1)
以指定的CPU亲和力运行JVM,这对很多人来说远非显而易见。无法从普通的 JVM 设置 CPU 亲和性。 (您可以使用 JNI 魔法,但要使用龙。)
是的,您不能通过我知道的标准 java 选项设置关联性和处理器优先级...在 Windows 上,您需要的命令是启动(在 32 位 Windows 上它没有关联选项不过)
内存使用量可以设置为您提到的参数。对于 CPU,优先级并没有限制。我查了谷歌,发现有工具可以限制特定进程的CPU使用率。我现在正在尝试。
@demotics2002,好吧,如果您在任务管理器/顶部观察进程 - 是的,它会达到 100%(或任何线程以最大运行速度),但是这是 b/c 你没有其他进程争夺 CPU 时间。如果是这样,他们将享受某些好处。是的,CPU 没有运行“空闲”进程。
JVM 有一个参数 -XX:ActiveProcessorCount=JVM 无法控制 CPU 使用率或优先级。
JVM 可以控制最大/最小内存使用量。
有一个解决方法。可以在单独的 [Docker 容器][1] 中运行每个 JVM。并控制每个容器的资源(内存、CPU、网络、IO)分配。这正是 Docker 容器的附加值。
[1]:JVM 无法控制 CPU 使用率和优先级。然而,您可以在单独的 Docker 容器中运行每个 JVM。并控制每个容器的资源分配。这正是 Docker 容器的附加值。
【讨论】:
你忘了说老版本的JVM,包括8,不理解Docker抽象,不会依赖容器设置。这仅适用于最新版本的 JVM,并且 JVM 8 仍然是主要版本。 我强烈反对,请再研究一下 Docker 的架构。 JVM 与容器技术无关且完全无视。我们确实同意:JVM 依赖容器设置是一种不稳定的设计选择。 你可以不同意,但如果你用谷歌搜索“jvm docker”并检查前几篇文章或文章会更有用。之后,您可以根据blog.csanchez.org/2017/05/31/… 在您选择的终端中简单地运行 2 个命令。我刚刚做了,它证实了我的怀疑。 分歧的来源是如何指定和绑定HW资源(CPU、mem、storage、NTWK)。在我所有的情况下,我都在硬编码资源的边界。如果您尝试从您遇到编程挑战的当前容器功能计算/计算边界,大多数情况下都可以通过使用预边界图像来避免。【参考方案3】:Docker 提供了资源管理选项来限制运行 docker 容器的 cpu 访问。查看 Docker 文档中 Limit a container's resources 中的 docker run
提供的 CFS 调度程序选项,例如:
--cpus=<value>
- 指定容器可以使用多少可用 CPU 资源。例如,如果宿主机有两个 CPU,而您设置--cpus="1.5"
,则容器最多保证 1 个半的 CPU。这相当于设置--cpu-period="100000"
和--cpu-quota="150000"
。在 Docker 1.13 及更高版本中可用。--cpuset-cpus
- 限制容器可以使用的特定 CPU 或内核。如果您有多个 CPU,则容器可以使用的逗号分隔列表或连字符分隔的 CPU 范围。第一个 CPU 编号为 0。有效值可能是0-3
(使用第一个、第二个、第三个和第四个 CPU)或1,3
(使用第二个和第四个 CPU)。
这些选项也可以通过 docker-compose 在部署 Docker swarm/stack 时使用,如 Compose file version 3 reference 下的 resources
所述:
version: '3' services: redis: image: redis:alpine deploy: resources: limits: cpus: '0.50' memory: 50M reservations: cpus: '0.25' memory: 20M```
注意: docker compose v2 中的 legacy resource options 现在仅限于 migration to v3 中的堆栈。
【讨论】:
【参考方案4】:在运行 jvm 8 或更早版本时,请注意内存和 CPU 选项。 有几篇关于这个的非常好的文章。看看吧:
https://developers.redhat.com/blog/2017/03/14/java-inside-docker/
https://jaxenter.com/nobody-puts-java-container-139373.html
话虽如此,容器化是微服务架构的正确方法,无论堆栈如何,jvm 也不例外。但是,重要的是要注意这些警告。
【讨论】:
【参考方案5】:Linux:
taskset -a -c 0,1,2,3 <program>
仅在核心 0、1、2 和 3 上运行程序及其子线程。
【讨论】:
【参考方案6】:在这种情况下,在移动模拟器(例如 android)上运行应用程序可能会有所帮助。
使用它,您可以模拟具有特定 CPU/内存的移动设备。因此,您应该获得与具有较慢 CPU 和较少 RAM 的设备相当的性能。
Android/诺基亚模拟器是免费的,可从诺基亚/谷歌网站的开发者部分下载。
【讨论】:
【参考方案7】:https://github.com/haosdent/jcgroup jcgroup 是您的最佳选择。您可以使用此库来限制 CPU 份额、磁盘 I/O 速度、网络带宽等。
【讨论】:
【参考方案8】:对于 CPU,你可以试试我的新库 :)。
https://github.com/dyorgio/cpu-watcher
使用示例:
// Limit process by PID to 25% of host cpu usage
CpuWatcher cpuWatcher = new CpuWatcher(pid, 25f);
cpuWatcher.start();
【讨论】:
以上是关于限制java应用程序的内存和cpu使用的主要内容,如果未能解决你的问题,请参考以下文章
Docker——JVM 感知容器的 CPU 和 Memory 资源限制