How to avoid memory leaks with View - enthought

With the following program:
from traits.api import HasTraits, Int, Instance
from traitsui.api import View
class NewView(View):
def __del__(self):
print('deleting NewView')
class A(HasTraits):
new_view = Instance(NewView)
def __del__(self):
print('deleting {}'.format(self))
a = Int
def default_traits_view(self):
new_view = NewView('a')
return new_view
running
a = A()
del(a)
returns
deleting <__main__.A object at 0x12a016a70>
as it should.
If I do
a = A()
a.configure_traits()
and after closing the dialog:
del(a)
I have the same kind of message:
deleting <__main__.A object at 0x12a016650>
with no mention of the NewView being deleted.
In geneal, what are the good practices to avoid memory leaks with Traits and TraitsUI?

What's going on here is that the NewView object is involved in a reference cycle, and the objects in that cycle don't get automatically collected as part of CPython's primary reference-counting-based object deallocation mechanism. However, they should be eventually collected as part of CPython's cyclic garbage collector, or you can force that collection by doing a gc.collect(), so there should be no actual long-term memory leak here.
Ironically, attempting to detect that eventual collection by adding a __del__ method to NewView hinders the process, since it renders the NewView object uncollectable: at least in Python 2, Python won't try to collect cycles containing objects that have __del__ methods. See the gc docs for details. (Python 3 is somewhat cleverer here, thanks to the changes outlined in PEP 442.) So with the __del__ method, using Python 2, there will indeed be a slow memory leak over time. The solution is to remove the __del__ method.
Here's a graph showing the reference cycle (actually, this shows the whole strongly-connected component of the object graph containing the NewView object): nodes are the objects involved, and arrows go from referrers to referents. In the bottom right portion of the graph, you see that the NewView object has a reference to its top-level Group (via the content attribute), and that Group object has a reference back to the original view (the container attribute). There are similar cycles going on elsewhere in the view.
It's probably worth opening a feature request on the Traits UI tracker: in theory, it should be possible to break the reference cycles manually when the view is no longer needed, though in practice that might require significant reworking of the Traits UI source.
Here's some code that demonstrates that (with the __del__ methods removed) a call to gc.collect does collect the NewView object: it stores a weak reference to the view on the A instance, with a callback that reports when that view is garbage collected.
from traits.api import HasTraits, Int, Instance
from traitsui.api import View
import gc
import weakref
class NewView(View):
pass
def report_collection(ref):
print("NewView object has been collected")
class A(HasTraits):
a = Int
def default_traits_view(self):
new_view = NewView('a')
self.view_ref = weakref.ref(new_view, report_collection)
return new_view
def open_view():
a = A()
a.configure_traits()
print("Collecting cyclic garbage")
gc.collect()
print("Cyclic garbage collection complete")
On my machine, here's what I see when open_view is called:
>>> open_view()
Collecting cyclic garbage
NewView object has been collected
Cyclic garbage collection complete

Related

ScalaFX - How to get the title of a Scene using a method

I am using ScalaFX and trying to learn how it works. As an exerpiment (not what I will do in production) I want a method that gets the title of a window.
So here is my Graph.scala file:
package graphing
import scalafx.application.JFXApp
import scalafx.scene.Scene
import scalafx.scene.paint.Color
class Graph {
val app = new JFXApp {
stage = new JFXApp.PrimaryStage {
title = "First GUI"
scene = new Scene {
fill = Color.Coral
}
}
}
def getTitle() = {
app.stage.getTitle
}
def generateChart(args: Array[String]) = app.main(args)
}
Here is my driver object that makes use of this Graph class:
package graphing
import graphing.Graph
object Driver extends App {
val graph = new Graph
println(graph.getTitle())
graph.generateChart(args)
}
However, this does not work due to the line
println(graph.getTitle())
The error that is thrown:
Could someone kindly explain what is going on and how I can achieve my goal here?
The problem here concerns JavaFX (and hence, ScalaFX) initialization.
Initializing JavaFX is a complex business. (Indeed, I only recently learned that it was even more complicated than I originally believed it to be. Refer to this recent answer here on StackOverflow for further background. Fortunately, your problem is a little easier to resolve.)
ScalaFX simplifies JavaFX initialization greatly, but requires that the JFXApp trait be used as part of the definition of an object.
JFXApp contains a main method, which must be the starting point of your application; it is this method that takes care of the complexities of initializing JavaFX for you.
In your example, you have your Driver object extend scala.App, and so it is App's (and hence, Driver's) main method that becomes the starting point of your own application. This is fine for a regular command line interface (CLI) application, but it cannot be used with ScalaFX/JavaFX applications without a great deal of additional complexity.
In your code, JFXApp's main method never executes, because, as it is defined as a class member, it is not the main method of a Scala object, and so is not a candidate for automatic execution by the JVM. You do call it manually from your Graph.generateChart() method, but that method itself is not called until after you try to get the title of the scene, hence the NPE as the stage has not yet been initialized.
What if you put the graph.generateChart(args) call before the println(graph.getTitle()) statement? Will that fix it? Sadly, no.
Here's why...
JFXApp also performs one other bit of magic: it executes the construction code for its object (and for any other classes extended by that object, but not for extended traits) on the JavaFX Application Thread (JAT). This is important: only code that executes on the JAT can interact directly with JavaFX (even if through ScalaFX). If you attempt to perform JavaFX operations on any other thread, including the application's main thread, then you will get exceptions.
(This magic relies on a deprecated Scala trait, scala.DelayedInit, which has been removed from the libraries for Scala 3.0, aka Dotty, so a different mechanism will be required in the future. However, it's worth reading the documentation for that trait for further background.)
So, when Driver's construction code calls graph.generateChart(args), it causes JavaFX to be initialized, starts the JAT, and executes Graph's construction code upon it. However, by the time Driver's constructor calls println(graph.getTitle()), which is still executing on the main thread, there are two problems:
Graph's construction code may, or may not, have been executed, as it is being executed on a different thread. (This problem is called a race condition, because there's a race between the main thread trying to call println(graph.getTitle()), and the JAT trying to initialize the graph instance.) You may win the race on some occasions, but you're going to lose quite often, too.
You're trying to interact with JavaFX from the main thread, instead of from the JAT.
Here is the recommended approach for your application to work:
package graphing
import scalafx.application.JFXApp
import scalafx.scene.Scene
import scalafx.scene.paint.Color
object GraphDriver
extends JFXApp {
// This executes at program startup, automatically, on the JAT.
stage = new JFXApp.PrimaryStage {
title = "First GUI"
scene = new Scene {
fill = Color.Coral
}
}
// Print the title. Works, because we're executing on the JAT. If we're NOT on the JAT,
// Then getTitle() would need to be called via scalafx.application.Platform.runLater().
println(getTitle())
// Retrieve the title of the stage. Should equal "First GUI".
//
// It's guaranteed that "stage" will be initialized and valid when called.
def getTitle() = stage.title.value
}
Note that I've combined your Graph class and Driver object into a single object, GraphDriver. While I'm not sure what your application needs to look like architecturally, this should be an OK starting point for you.
Note also that scala.App is not used at all.
Take care when calling GraphDriver.getTitle(): this code needs to execute on the JAT. The standard workaround for executing any code, that might be running on a different thread, is to pass it by name to scalafx.application.Platform.runLater(). For example:
import scalafx.application.Platform
// ...
Platform.runLater(println(ObjectDriver.getTitle()))
// ...

Actor accessing things out of scope

I'm using the Akka libraries.
What happens when multiple actors call a function on an object? Would this block other actors from accessing the object?
The reason I ask this is because I want to use JBCrypt with akka actors. And since we can encrypt multiple strings concurrently I have each actor calling JBcrypt.hash(...). Not sure how it works since I think, in scala, objects exist in one place, and I feel like multiple actors using the same object (library) might block the concurrency from actually happening.
Multiple actors calling a function in an object that calls a library will not block unless the library being called uses concurrency control mechanisms such as sychronized, ThreadLocal or an object lock.
For example, calling print on the below Printer object will block:
class BlockingPrinter(){
def print(s: String) = synchronized{s}
}
object Printer{
val printer = new BlockingPrinter()
def print(str: String) = printer.print(str)
}
But calling it on the below Printer object will not
class NonBlockingPrinter(){
def print(s: String) = s
}
object Printer{
val printer = new NonBlockingPrinter()
def print(str: String) = printer.print(str)
}
In summary, the library that you're calling is the one that decides how concurrency is handled. Not the fact that you're calling an object.
It depends on how the function is implemented. If the function accessed some internal mutable state and tries to synchronize in order to achieve thread safety then there is a problem. If it's a pure function and does not access any external state, then it is safe. If the function has the mutable state at least it must contain the mutable state to itself.

How to group object lifecycle together in Swift without a strong reference cycle?

Background
I'm relatively new to Swift (coming from a C++ and C#) background, and I'm struggling with how best to design some of my data model types and interfaces. ARC seems great and makes certain things easier, but I find myself running into certain design challenges.
Problem
Suppose we'd like to represent some complicated, interconnected data with a mix of different objects (of classes A, B, and C). For example, say each A object should have an associated B object and multiple C objects. The A object must also respond to changes in its linked objects (eg. when a C object changes, the associated A must update its own internal state and notify its B too).
Due to ARC, we can't simply have these objects all strongly reference each other, otherwise we end up with a strong reference cycle (and memory leaks).
Fortunately Swift provides us with weak and unowned references, so we can always set up our relationships like this (dashed lines are weak references):
This is workable but can be somewhat cumbersome to set up, especially for lots of interconnected objects. It's even more cumbersome if we are using third-party classes (which we can only modify via extensions).
Also, if the main A object is only using weak references, it can't actually keep its associated B or C objects alive on its own.
Reversing the direction of our weak references will fix that particular problem, but it introduces its own drawbacks.
For example, suppose a view or controller only needs to interface with the C objects. However, if it only maintains references to these C objects, and those C objects only have weak references to the backing A object, that A object might be freed. This basically forces client code to keep a reference to the A object around to prevent the C objects it cares about from being orphaned.
Wishful Thinking
Ideally I wish to simply and easily tie the lifecycle of these objects together, but without producing a memory leak. In other words, I'd like to create an A object (which would then create its own associated B and C objects) and have them all keep each other alive, but only as long as external code had at least one reference to any one of these "bundled" objects.
Is this possible (and practical) in Swift?
More Specifics
I wasn't sure if the details would clarify or cloud things, but if it helps... one of the scenarios where I've run into this is modeling data and storing it with Core Data.
For example, A is the "public" programmer-friendly interface (conforming to a standardized data protocol), B is the "private" backing storage (a Core Data entity), and C is a helpful encapsulation of complicated data.
There are also some associated D & E classes I left out which are also associated with the main A object. These are themselves much like our A class here, ie. a public interface to data models with their own complicated multi-object relationships, but fundamentally suffer from the same issues as our A to C relationship.
In other words, client code might only need to interface with a D, but modifying the D on its own won't function correctly unless the associated A object is somehow kept alive too.
Somewhat Tangential
This makes me wonder how Core Data entities manage their relationships without introducing strong reference cycles. For example, you might have X, Y, and Z entities all relating to and relying on each other.
Based on the classes that are auto-generated, I don't see any weak references. How can these managed objects maintain references to each other without memory leaks?
I see two possible strategies you could use (there could be others) :
1) Embrace the strong reference cycles and dismantle it explicitly
2) Make the various classes autonomous by enabling them to dynamically instantiate their referenced objects as needed.
For #1, you could either require the calling code to call some "clean-up" method to break the strong references (e.g. methods of the A,B,C ... classes that set their strong references to nil). Or, you could create a container class that instantiates the objects and hold the strong references and then let the calling code own that container.
For #2, the various classes would only need a hierarchical Strong-><-Weak relationship and "children" object would lazily re-instantiate their "parent" instance as needed (similar to CoreData faulting on ManagedObjects).
Core Data is a reasonably good example of how you'd want to attack this kind of problem. In Core Data there is a managed object context that actually owns all the objects. Managed objects are proxies which may in fact be faults.
Given your example (a backing store that is a managed object), you'd address this by storing the managed object ID rather than the object itself. When you want to access the underlying object, you ask the context for it, and it either returns you the existing objet or faults one into existence.
If you have your own (non Core Data) system, you can create a similar approach with NSCache and NSDiscardableContent that will keep objects around when they're being actively used, and purge them when they're not. You just need a mechanism for reinstantiating them when needed.
But the key is to work with IDs or proxies rather than the actual object, and hold onto the actual objects in a container that manages memory, just like Core Data.
I'm reading your problem and I keyed in on the following phrase, “The A object must also respond to changes in its linked objects”.
In Swift, properties are generally used to show ownership.
class A {
let bee: Bee = Bee()
let cees: [Cee] = [Cee(), Cee()]
}
class Bee {
}
class Cee {
}
Inter-instance communication can be done in a few ways.
Delegation
class A: BeeDelegate, CeeDelegate {
let bee: Bee = Bee()
let cees: [Cee] = [Cee(), Cee()]
func beeDidChange(_ bee: Bee) {
}
func ceeDidChange(_ cee: Cee) {
}
init() {
bee.delegate = self
cees.forEach { $0.delegate = self }
}
}
protocol BeeDelegate {
func beeDidChange(_ bee: Bee)
}
class Bee {
weak var delegate: BeeDelegate?
}
protocol CeeDelegate {
func ceeDidChange(_ cee: Cee)
}
class Cee {
weak var delegate: CeeDelegate?
}
Notification
Here is a partial Notification solution. All that’s needed is posting the change notifications from within Bee and Cee.
class A: BeeDelegate, CeeDelegate {
let bee: Bee = Bee()
let cees: [Cee] = [Cee(), Cee()]
func beeDidChange(_ notification: Notification) {
}
func ceeDidChange(_ notification: Notification) {
}
var center = NotificationCenter.default
init() {
center.addObserver(forName: .beeDidChange, object: nil, queue: nil, using: beeDidChange)
center.addObserver(forName: .ceeDidChange, object: nil, queue: nil, using: beeDidChange)
}
deinit() {
center.removeObserver(self)
}
}
extension Notification.Name {
static let beeDidChange = Notification.Name(rawValue:"BeeDidChange")
}
extension Notification.Name {
static let ceeDidChange = Notification.Name(rawValue:"CeeDidChange")
}
KVO
Key-Value Observing is a complex topic and is not easy to cover without all the details.

How to know the used buffer size of a SourceQueue in akka?

So I'm a fan of using Source.queue and now I want to monitor it, to know how much of the buffer it's being used at certain point. Yet I haven't seen a way to know such info. Only thing which comes to mind is a workaround in which I have a mutable number to which I add when I offer an element, and subtract, when the operation has been completed.
You could change the QueueSource class to provide a materialized queue that exposes its internal buffer size. This can be done by creating a new trait - e.g.
trait SourceQueueWithCompleteAndSize[T] extends SourceQueueWithComplete[T] {
def size: Int
}
Then, in the final part of the stage (see the original code for reference), you need to provide your new trait implementation instead of the SourceQueueWithComplete. You should be able to access the size of the internal buffer with the used method.
(stageLogic, new SourceQueueWithCompleteAndSize[T] {
// other methods implementations
override def size: Int = stageLogic.buffer.used // NEW BIT
})
It's a fair amount of code to copy, but it might be better than adding an external counter around your stage. Might as well be a valid contribution to akka-stream-contrib.

Pass data to a ScalaFX JFXApp

I wrote a GUI in ScalaFX whichs works quite well when testing it isolated. Things to mention:
The "real" application itself already has a main method, and only that one should be used to start the application, not the one I get when extending JFXApp. So the call to the main method of JFXApp is done manually, from the outside
It should be possible to pass a data structure to the JFXApp, so I added a setter
The whole startup procedure looks like this:
def main(args: Array[String]) {
...
...
JFXGui.setData(data)
JFXGui.main(Array())
}
The problem:
I cannot draw the contents of the data object as long as the main method of the JFX object is not called, so setData is really just a simple setter method. The idea is that JFXGui should draw the data as soon as possible after JFXGui.main was called. But: how can I realize this inside of JFXGui? Is there something like an "onready"-method?
In the above code, I tried to put the call to the setter after the call to the main method, so that the setter can trigger the drawing. What I hadn't in mind is that JFXGui.main is blocking forever, therefore the call to the setter is unreachable code.
How could I fix this? any help is appreciated, thanks.
edit:
JFXGui is the name of my ScalaFX UI:
object JFXGui extends JFXApp {
private var data: Data = _
def setData(data: Data) {
this.data = data;
}
// tons of ScalaFX related things which visualize the data object
// ...
}
Solution 1 (reusing JFXApp)
The Gui object no longer should be an object, but a class with constructor parameters.
class Gui(data: Data) extends JFXApp {
//your existing code without the field data and the method setData()
}
In the startup class:
new Gui(data).main(Array())
Solution 2 (Custom init)
You do not necessarily have to use JFXApp in order to run your application. I suggest you having a look at the source code of JFXApp.main() and the class AppHelper. They contain ~10 lines of code combined so you can just copy their source code and tailor it to your needs.