提升记忆力

您好我有一个使用java.swing.timer的应用程序,这是在循环中。 问题是我的Windows内存进程仍然发光,并且不要停止。 我试图清理我的变量,使用System.gc()等……并且不工作。 我用一个样本来测试这个用线程,timerstack和swing计时器,我把它添加到一个jcombobox中,内存仍然在boost。

代码如下:

//我的计时器

@Action public void botao_click1() { jLabel1.setText("START"); timer1 = new java.util.Timer(); timer1.schedule(new TimerTask() { @Override public void run() { adicionarItens(); limpar(); } }, 100, 100); } @Action public void botao_click2() { thread = new Thread(new Runnable() { public void run() { while (true) { adicionarItens(); try { Thread.sleep(100); limpar(); } catch (InterruptedException ex) { Logger.getLogger(MemoriaTesteView.class.getName()).log(Level.SEVERE, null, ex); } } } }); thread.start(); } private void limpar() { // CleanUp array and jcombobox texto = null; jComboBox1.removeAllItems(); jComboBox1.setVisible(false); //jComboBox1 = null; System.gc(); } private void adicionarItens() { //AddItens texto = new String[6]; texto[0] = "HA"; texto[1] = "HA"; texto[2] = "HA"; texto[3] = "HA"; texto[4] = "HA"; texto[5] = "HA"; //jComboBox1 = new javax.swing.JComboBox(); jComboBox1.setVisible(true); for (int i = 0; i < texto.length; i++) { jComboBox1.addItem(texto[i].toString()); } System.out.println("System Memory: " + Runtime.getRuntime().freeMemory() + " bytes free!"); } 

请帮助! =(

目前尚不清楚您发布的一小段代码实际上是否存在问题。

无论哪种方式,您无法控制您想要控制的内容

-Xmx仅控制Java堆,它不控制JVM对本机内存的消耗,根据实现消耗完全不同。

从以下文章感谢内存(了解JVM如何在Windows和Linux上使用本机内存)

维护堆和垃圾收集器使用您无法控制的本机内存。

需要更多的本机内存来维护维护Java堆的内存管理系统的状态。 必须分配数据结构以跟踪免费存储并记录收集垃圾时的进度。 这些数据结构的确切大小和性质因实现而异,但许多数据结构与堆的大小成正比。

并且JIT编译器使用本机内存,就像javac一样

字节码编译使用本机内存(与gcc等静态编译器需要运行内存的方式相同),但JIT的输入(字节码)和输出(可执行代码)也必须存储在本机内存中。 包含许多JIT编译方法的Java应用程序比较小的应用程序使用更多的本机内存。

然后你有使用本机内存的类加载器

Java应用程序由定义对象结构和方法逻辑的类组成。 它们还使用Java运行时类库(例如java.lang.String)中的类,并且可以使用第三方库。 只要它们被使用,这些类就需要存储在内存中。 如何存储类因实现而异。

我甚至不会开始引用关于Threads的部分,我认为你会认为-Xmx不能控制你认为它控制的是什么,它控制着JVM堆,而不是JVM堆中的所有内容,并且堆占用了更多的本机记忆,你指定的管理和簿记。

我在任何地方都没有看到任何OutOfMemoryExceptions

无论如何,你关心的是你无法控制的

您应该关注的是控制中的内容,即确保您不会持续超过您需要的引用,并且您不会不必要地复制内容。 Java中的垃圾收集例程已经过高度优化,如果您了解其算法的工作原理,您可以确保您的程序以最佳方式运行,以使这些算法工作。

Java Heap Memory与其他语言的手动管理内存不同,这些规则不适用

什么被认为是其他语言中的内存泄漏与Java及其垃圾收集系统不同的原因/根本原因。

Java内存中很可能不会被泄漏的单个超级对象(在其他环境中悬挂引用)消耗掉。

由于垃圾收集器所处的范围以及许多其他可能在运行时变化的内容,中间对象可能会被垃圾收集器保持的时间长于预期。

示例:垃圾收集器可能会确定存在候选者,但是因为它认为仍有大量内存需要在那个时间段将它们清除出来并且它会花费太多时间,并且它会等到内存压力越来越大。

垃圾收集器现在真的很好,但它不是魔术,如果你做退化的事情,它将导致它不能最佳地工作。 互联网上有很多关于所有JVM版本的垃圾收集器设置的文档。

这些未引用的对象可能还没有达到垃圾收集器认为需要它们从内存中清除它们的时间,或者可能存在一些其他对象( List )所持有的对它们的引用,例如你没有实现仍然指向那个对象。 这是Java中最常被称为泄漏的泄漏,更具体地说是参考泄漏。

示例:如果您知道需要使用StringBuilder构建4K String使用新的StringBuilder创建它new StringBuilder(4096); 不是默认值,它就像是32并且会立即开始创建垃圾,它可以代表你认为对象应该是大小明智的很多倍。

您可以发现使用VisualVM实例化了多少类型的对象,这将告诉您需要了解的内容。 没有一个闪烁的大灯指向单个类的单个实例,它说“这是大内存消费者!”,这是除非你只有一个char[]实例读取一些大量文件,这也是不可能的,因为很多其他类在内部使用char[] ; 然后你几乎已经知道了。

我没有看到任何提到OutOfMemoryError

您的代码中可能没有问题,垃圾收集系统可能没有足够的压力来启动和释放您认为应该清理的对象。 您认为问题可能不是,除非您的程序与OutOfMemoryError崩溃。 这不是C,C ++,Objective-C或任何其他手动内存管理语言/运行时。 你无法在你期望的细节层面上决定内存中的内容。

理论上,Java不受基于C语言可能具有的“泄漏”的影响。 但是,设计一种以或多或少无限制的方式增长的数据结构仍然非常容易,无论你是否打算这样做。

当然,如果您安排基于计时器的任务等,它们将一直存在,直到时间到期并且任务已完成(或取消),即使您没有保留对它们的引用。

此外,一些Java环境(Android因此而臭名昭着)以不受普通GC操作影响的方式分配图像等,并且可能导致堆以无限制的方式增长。