Tag: 垃圾收集

finalize()如何在java中工作?

所以,我最近在Java中发现了finalize方法(不知道为什么我之前错过了它,但它确实存在)。 这似乎可能是我正在处理的许多问题的答案,但我想首先获得更多信息。 在线,我发现这个图表说明了垃圾收集和完成的过程: 几个问题: 这发生在一个单独的线程中,对吗? 如果我在finalize期间实例化一个新对象会发生什么? 这是允许的吗? 如果我从finalize调用静态方法会发生什么? 如果我在finalize中建立对象的新引用会发生什么? 我想我应该解释为什么我感兴趣。 我经常使用LWJGL,似乎如果我可以使用finalize来使Java对象自动清理OpenGL资源,那么我可以在API方面做一些非常好的事情。

长GC在应用程序中暂停

我目前正在运行一个需要最大堆大小为16GB的应用程序。 目前我使用以下标志来处理垃圾收集。 -XX\:+UseParNewGC, -XX\:+UseConcMarkSweepGC, -XX:CMSInitiatingOccupancyFraction=50, -XX\:+DisableExplicitGC, -XX\:+PrintGCDateStamps, -XX\:+PrintGCDetails, -Xloggc\:/home/user/logs/gc.log 但是,我注意到在一些垃圾收集期间,应用程序会锁定几秒钟然后继续 – 这是完全不可接受的,因为它是游戏服务器。 我的垃圾收集日志可以在这里找到。 关于我应该改变什么以减少这些长时间停顿的任何建议将不胜感激。

GC中的GC.AddMemoryPressure等效

项目:Java,JNI(C ++),Android。 我将通过创建一个托管包装类来管理本机C ++对象的生命周期,该类包含一个指向本机对象的指针(作为一个长成员),并将删除其中重写的finalize()方法中的本机对象。 有关详细信息,请参阅此问 C ++对象不消耗其他类型的资源,只消耗内存。 对象的内存占用量不是很高,但它基本上高于Java中64位的长度。 有没有办法告诉Java的GC,我的包装器不仅仅是一个很长的值,而且在运行垃圾收集之前创建数百万个这样的对象并不是一个好主意? 在.NET中有一个GC的AddMemoryPressure ()方法,正是出于这个目的。 Java中是否存在等价物?

Java GC – 有一种方法可以确定收集哪些对象

我正在尝试使用-verbosegc标志来监控应用中的gc活动。 我可以看到有完整和次要的集合,但有没有办法确定(确定事件/ vm标志/其他什么)实际收集的对象? 谢谢!

无法访问的对象不是从堆中收集的垃圾

我在JVM堆(Java 1.7)中遇到了无法访问的对象。 正如你从图片中看到的那样(图片上的所有类都无法访问),我们有超过74%的对象没有参考,所以它应该被收集起来。 这个状态在我们的tomcat 7服务器上运行3周之后,只运行探测监控应用程序,tomcat管理器和我们的webapp,这可能是问题的根源。 我们的应用程序基于JSF 1.2,在客户端上保存状态,如下图所示 – 主要使用ViewSaveState的char数组。 当我从jVisualVM手动运行GC时,它会删除所有无法访问的对象,并且在堆达到其限制的3周之前一切正常。 如何清除某些物体? 我们的JVM参数 -Dcom.sun.management.jmxremote=true -Dcom.sun.management.jmxremote.port=29001 -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false -Djava.rmi.server.hostname= -Dorg.apache.el.parser.SKIP_IDENTIFIER_CHECK=true -Xms320m -Xmx2500m -XX:MaxPermSize=500m -XX:PermSize=96m -verbose:gc -Xloggc:/var/log/gc.log -XX:+PrintGCTimeStamps -XX:+PrintGCDetails -Xdebug -Xrunjdwp:transport=dt_socket,address=1044,server=y,suspend=n -XX:+CMSClassUnloadingEnabled -XX:+UseConcMarkSweepGC OutOfMemoryError的STACKTRACES 我认为原因隐藏在其他地方,堆栈跟踪来自app的不同部分。 可能存在一些泄漏,但堆栈跟踪仅报告最后一个组件,该组件在没有任何内存的情况下及时声明了一些内存。 java.lang.OutOfMemoryError: Java heap space at java.util.LinkedHashMap.createEntry(LinkedHashMap.java:442) at java.util.HashMap.addEntry(HashMap.java:888) at java.util.LinkedHashMap.addEntry(LinkedHashMap.java:427) at java.util.HashMap.put(HashMap.java:509) at sun.util.resources.OpenListResourceBundle.loadLookup(OpenListResourceBundle.java:134) at sun.util.resources.OpenListResourceBundle.loadLookupTablesIfNecessary(OpenListResourceBundle.java:113) at sun.util.resources.OpenListResourceBundle.handleGetObject(OpenListResourceBundle.java:74) at sun.util.resources.TimeZoneNamesBundle.handleGetObject(TimeZoneNamesBundle.java:75) at java.util.ResourceBundle.getObject(ResourceBundle.java:389) […]

导致GC流失一致的技术

我正在寻找基准如何在与大量正在进行的垃圾收集竞争时执行的操作。 我之前已经对它在稳定的单线程运行中的行为进行了基准测试,现在我想在更加紧张的JVM中进行相同的测试; 本质上我想让背景线程以合理一致的速度创建和销毁对象。 我正在寻找有关如何实施稳定但GC密集型操作的建议。 它需要完成几个目标: 在GC中花费相当多的时间(比方说,20-50%) 随着时间的推移做大致一致的工作量,并为GC创建类似一致的工作量 避免泛滥堆并触发Java heap space错误 避免GC过载并触发GC overhead limit exceeded错误

处理后将对象设置为null是一个好习惯吗?

我有这样的场景: public void processData(String name,String value) { /* line 1 */ MyDTO dto = new MyDTO(); /* line 2 */ dto.setName(name); /* line 3 */ dto.setValue(value); /* line 4 */ sendThroughJMSChannel(dto); /* line 5 */ dto = null; //As a best practice, should I do this ? } 在第4行之后的程序中,我不需要dto进行进一步处理。 作为最佳实践,我应该将dto设置为null如第5行所示,还是忽略它? 通过将其设置为null ,我期待快速垃圾收集。 这是对的吗?

有没有办法在Java中强制使用弱的和/或软引用的对象?

这是我的用例。 我们正在尝试缩小应用程序中潜在的内存泄漏,我们正在使用内存分析工具对堆进行快照,以便我们可以查找对象实例和引用。 (如果它有帮助,我们正在使用YourKit。) 此应用程序广泛使用动态和CGLIB代理,最终在WeakHashMaps中存储大量类和类加载器的引用。 在我们的测试用例运行之后,我们期望对对象X及其类加载器的所有硬引用都消失了,但是由于测试用例中涉及很多代理,我们还有许多弱/软引用。 (我只能找到WeakHashMap引用,但是YourKit将弱引用和软引用都包含在摘要中的一个行项中,所以我不能确定我在某个地方没有错过软引用。) 即使在从JVM请求完整GC之后也是如此。 (在服务器模式下使用sun 1.6.0_23 JDK。) 似乎 JVM承认只有弱/软引用这些对象,但我不能强迫它对GC这些事情是100%肯定的。 (所以,我想要的是,它完全从堆中消失,其permgen的类加载器使用也会消失。) 任何人都知道配置和/或强制JVM处理仅软/弱引用的对象的方法吗?

是否有可能在Java中有多个堆?

是否有可能在Java中有多个堆? 如果有可能那么它会在哪些情况下发生?

堆参数对GC /性能的影响?

大多数网上的地方,我得到关于堆参数的信息 -Xms set initial Java heap size -Xmx set maximum Java heap size 当我提到-Xms 512M -Xmx 2048M参数时,这是我的理解/问题, -Xms: –我的理解是如果我的java进程实际上只需要200M,提到-Xms 512M,java进程仍将只分配200M(实际内存需要)而不是500M。 但是如果我已经知道我的应用程序将在启动时使用这个512M内存,那么指定少于将会影响性能,因为无论如何堆块需要resize,这是昂贵的操作。 在与我的同事讨论时 ,默认情况下,GC将触发60%的Xms值。 那是对的吗 ? 如果是,是次要GC还是完全GC依赖于Xms值? 关于Xms的更新: –在读取JVM堆参数之后这似乎是真的,但默认情况下值是60%并且是依赖于Xms值的次要GC还是完整GC? -Xmx: –我的理解是提到-Xmx 2048M,java进程实际上是要从OS中保留2048M内存,因为另一个进程无法给它的共享。如果java进程无论如何都需要2048M以上的内存,那么内存不足将被抛出。 另外我认为在-Xmx的值上有一些Full GC触发器的关系。 因为我观察到的是当内存达到Xmx的70%时,Full GC发生在jconsole中。 那是对的吗? 配置: –我使用的是linux box(64位JVM 8)。 默认GC即并行GC