作为MSIL和Java字节码之间的差异问题的一种跟进?,Java虚拟机的工作方式(主要)差异或相似之处是什么?.NET Framework 公共语言运行时(CLR)有效吗?
还有,是 .NET框架 CLR是"虚拟机"还是没有虚拟机的属性?
我有一个关于JVM内存管理的问题(至少对于SUN的内存管理问题).
我想知道如何控制JVM将未使用的内存发送回操作系统(在我的情况下为Windows)这一事实.
我写了一个简单的java程序来说明我的期望.使用-Dcom.sun.management.jmxremote选项运行它,以便您也可以使用jconsole监视堆.
使用以下程序:
package fr.brouillard.jvm;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.LinkedList;
import java.util.List;
public class MemoryFree {
private BufferedReader reader = new BufferedReader(new
InputStreamReader(System.in));
private List<byte[]> usedMemory = new LinkedList<byte[]>();
private int totalMB = 0;
private int gcTimes = 0;
public void allocate(int howManyMB) {
usedMemory.add(new byte[howManyMB * 1024 * 1024]);
totalMB += howManyMB;
System.out.println(howManyMB + "MB allocated, total allocated: " +
totalMB + "MB");
}
public void free() {
usedMemory.clear();
}
public void gc() {
System.gc(); …Run Code Online (Sandbox Code Playgroud) 在线检查java和google搜索哈希表代码示例,似乎通过加倍来完成表的大小调整.
但是大多数教科书都说桌子的最佳尺寸是素数.
所以我的问题是:
加倍的方法是因为:
n+=2数并使用模数测试素数是O(loglogN)这很便宜)更新:
教科书中使用素数的方式是某些属性工作所必需的(例如,二次探测需要一个素数表来证明,例如,如果一个表不是完整的项目X将被插入).
发布为重复的链接一般要求增加任何数字,例如25%或下一个素数,并且答案接受说明我们加倍以保持调整大小操作"罕见",因此我们可以保证摊销时间.
这并没有回答这样一个问题:使用一个表格大小是素数并使用素数来调整大小甚至大于两倍.因此,我们的想法是保持主要大小的属性考虑调整大小开销
我正在XX:+UseParNewGC-XX:+UseConcMarkSweepGC为我的应用程序使用GC选项.
正如大多数人已经体验到的那样,JVM擅长将堆增加到最大堆大小,但它不会将内存释放回操作系统.我遇到了-XX:MaxHeapFreeRatio,-XX:MinHeapFreeRatio但对于并行垃圾收集器,这些都被忽略了.
是否有特殊选项可将JVM释放内存强制回OS以进行-XX:MaxHeapFreeRatio and -XX:MinHeapFreeRatio组合.
我打开了三个项目。其中之一——Spark——非常大。关闭 spark 后,内存使用量没有差异 - 正如 os/x 活动监视器报告的那样。注意:所有项目都在同一个 Intellij 实例中打开。
事实上,它只使用了 4GB 多一点。我现在只有两个项目打开。如果我关闭 Intellij 并重新启动它,这两个项目仅占用 1.5GB。
那么..如何“鼓励”Intellij 释放它正在使用的内存?它运行得很慢(例如跟不上我的打字速度)
更新我刚刚关闭了剩下的两个项目中较大的一个。仍然没有减少内存使用。剩下的项目是一个单独的 python 文件。所以此时 Intellij 应该在 512Meg 下使用!
当我使用OpenJDK 11(在Windows 10上为Zulu发行版)编译并运行以下非常简单的Java程序时:
public class GCTest {
public static void main(String[] args) {
System.out.println("Free memory before garbage collection: " + Runtime.getRuntime().freeMemory());
Runtime.getRuntime().gc();
System.out.println("Free memory after garbage collection: " + Runtime.getRuntime().freeMemory());
}
}
Run Code Online (Sandbox Code Playgroud)
看起来垃圾回收正在减少可用内存量:
Free memory before garbage collection: 266881496
Free memory after garbage collection: 7772200
Run Code Online (Sandbox Code Playgroud)
当我使用Oracle Java 8运行它时,不会发生这种情况:
Free memory before garbage collection: 254741016
Free memory after garbage collection: 255795064
Run Code Online (Sandbox Code Playgroud)
这是为什么?
这里和这里已经有类似的问题,但是JVM参数的改变都没有引出我同样的解决方案.我只是想减少我的JVM未使用的堆大小,以便它更接近地反映实际使用情况(将其释放到操作系统).我一直在使用YourKit来分析内存使用情况,它通常如下所示:
我在Windows 7 64位,8 GB RAM上运行intellIj IDEA Community Edition 64位.我已经编辑了.vmoptions这里找到的文件:C:\Program Files (x86)\JetBrains\IntelliJ IDEA Community Edition 14.1.5\bin\idea64.exe.vmoptions上面链接中提到的建议.第一个链接的答案实际上是错误的/过时的,但是2条评论链接到这里和这里看起来很有希望的文章.问题是,我已经尝试了所提到的所有不同的垃圾收集器,并且仍然看到上面显示的类似(不相同)的堆大小.
如何减少分配的堆大小(橄榄绿)以更准确地反映实际使用情况(蓝色)?垃圾收集不应该降低堆大小,而不是像目前那样增加它.
我已经尝试配置我的idea64.exe.vmoptions如下:
根据上面的最后一个链接,它声称
只有Serial GC和G1将未使用的内存释放到OS
它甚至可以直观地显示堆的减少方式.然而,我没有运气,并尝试了以下所有方面:发生了什么?
-XX:+UseSerialGC
和
-XX:-UseSerialGC
和
-XX:+UseG1GC
Run Code Online (Sandbox Code Playgroud)
和
-XX:-UseG1GC
Run Code Online (Sandbox Code Playgroud)
和
Both of the above together, with and without ("+/-")
Run Code Online (Sandbox Code Playgroud)
和
-XX:-UseAdaptiveSizePolicy
-XX:-UseParallelGC
Run Code Online (Sandbox Code Playgroud)
和
-XX:UseConcMarkSweepGC
和
-Xms128m
-Xmx750m
-XX:MaxPermSize=350m
-XX:ReservedCodeCacheSize=225m
-XX:+UseG1GC
-XX:SoftRefLRUPolicyMSPerMB=50
-ea
-Dsun.io.useCanonCaches=false
-Djava.net.preferIPv4Stack=true
-Djsse.enableSNIExtension=false
Run Code Online (Sandbox Code Playgroud)
和
-server
-Xms128m
-Xmx512m
-XX:MaxPermSize=250m
-XX:ReservedCodeCacheSize=150m
-XX:UseConcMarkSweepGC
-XX:SoftRefLRUPolicyMSPerMB=50
-ea
-Dsun.io.useCanonCaches=false
-Djava.net.preferIPv4Stack=true
Run Code Online (Sandbox Code Playgroud)
编辑: …
喜欢读一些答案后,这个和JEP-346,我已经意识到,G1确实释放内存返回给操作系统。
然而,它是否将内存释放回操作系统,甚至到了当前内存使用量可能低于初始堆内存的程度(即在此 JEP 之前,在我的情况下为 JDK11)?
假设我有一个 Java 11 VM在RAM上运行Xms并Xmx设置为,但是我只消耗大约. G1 会向操作系统释放足够的内存吗?5GB8GB1GB
我没有在任何地方找到任何文件说 G1 仅限于释放Xms记住阈值。
我在生产中观察到这一点,MemAvailable 一直减少到一个点,然后在 GC 之后,它在 8GB 的盒子上跃升至接近 30-35%。所以我假设它正在释放内存,这就是 MemAvailable 跳回的原因。
另外,向操作系统释放内存到底是什么意思,它是调用 free/unmap 吗?
我是Play框架的新手。我一直在生产模式下运行Play Framework2.7.x。实际上是最简单的代码:
package controllers
import javax.inject._
import play.api._
import play.api.mvc._
@Singleton
class HomeController @Inject()(cc: ControllerComponents) extends AbstractController(cc) {
def index() = Action { implicit request: Request[AnyContent] =>
Ok(views.html.index())
}
}
Run Code Online (Sandbox Code Playgroud)
运行时,我注意到对于每个请求,它都会增加更多的内存使用量。它增加了。在请求增加的阶段,应用程序使用的传入内存达到1Gb。我停止发送请求,但是我注意到该应用程序没有释放任何内存。
我的问题是-这个应用程序会释放它的占用内存吗,有什么方法可以在不重启应用程序的情况下做到这一点?
1)我们的应用程序:Spring boot,Java 8
2)我们使用的参数:xms = 256 MB,xmx = 2 GB
我们已经看到,java8 应用程序的已用堆大小并没有在适当的时候缩小。
在启动 Spring Boot/Java 8 应用程序时,我们应该与上面的 #2 一起使用任何其他参数,以便 GC 可以做得更好吗?
感谢您的帮助!