标签: java-assist

在导致内存碎片问题的次要 gc 之后,Java 对象不必要地升级到老年代

我们的应用程序面临一个奇怪的内存泄漏问题。

GC 配置:ParNew + CMS

某种类型的对象过早地被提升到老年代并导致严重的碎片问题。

  1. 幸存者有足够的空间来容纳这些物品
  2. 老化阈值是 15 个周期,并且没有在此基础上发生过早提升。

关于这些对象:这些是使用 Java 辅助库创建的代理对象。

由于这些对象的不必要的提升,老年代被污染的太快,严重的碎片正在发生。

我们的观察:

  1. 对象仅在 eden 中分配。没有大小相关的问题。
  2. 对象的范围非常小,有资格在下一次次要 gc 中进行 GC。
  3. 为了确保这一点,我们在finalize() 中打印了一些记录器,并观察到范围在请求后立即结束。就在第一次次要 GC 之后。

注意:finalize() 只是为了跟踪目的而添加的。即使没有 finalize() 老一代促销也会发生。

  1. 在一次次要 gc 之后:
  • 期望对象将被清除。
  • 但是对象被提升到老年代。在多个堆转储的帮助下,我们能够跟踪对象升级到老年代。
  1. 所有这些对象都在 old gen 中累积,并由 old gen GC 进行 GC。
  2. 此行为仅在生产服务器中可见,在测试环境中不可重现。

请建议如何进一步进行并解决此问题。

另一个有趣的更新:使用 G1GC,当使用 G1GC 时,对象会被正确清除。使用 finalize() 方法检查,在第一个循环之后,对象变得无法访问。在下一个小循环之后,对象不在那里。对于 G1GC,问题不存在。

java garbage-collection memory-leaks java-memory-leaks java-assist

5
推荐指数
0
解决办法
117
查看次数

Android下如何交换方法体

在纯 Java 中,使用插装和 Java 代理,有一种方法可以在运行时替换方法体。

不幸的java.lang.instrument.Instrumentation是在 Android 下不可用。

我已经检查了所有其他替代方案,例如这里在stackoverflow 中描述的替代方案,它指向过时的javassist-android实现。这令人惊讶地有效,但仅适用于新课程。

还有一篇名为Hot swapping code in Android的文章描述了如何在运行时再次加载类,而不是如何替换现有的类方法。

唯一处理这个问题的文章是一篇名为Android hacking:replace system classes methods with your own 的文章,它没有提供源代码并引用了 Dalvik,而不是 ART(因此它不适用于现代硬件)。

那么,有没有什么办法呢?

...

底线:我想要这样做的原因是在我的应用程序中跟踪特定的方法调用,就像调用此方法时(并在它之前执行某些操作)和此方法退出时(并对其执行一些操作)一样。这些方法是在运行时定义的,因此无法在编译时提前知道它们。

android dalvik dex java-assist

3
推荐指数
1
解决办法
446
查看次数