What Is a "Rooted Reference"

What is a rooted reference?

It means a GC root.

Have a read through this article, maybe it will help with your understanding:

GC roots are not objects in themselves but are instead references to objects. Any object referenced by a GC root will automatically survive the next garbage collection. There are four main kinds of root in .NET:

A local variable in a method that is currently running is considered to be a GC root. The objects referenced by these variables can always be accessed immediately by the method they are declared in, and so they must be kept around. The lifetime of these roots can depend on the way the program was built. In debug builds, a local variable lasts for as long as the method is on the stack. In release builds, the JIT is able to look at the program structure to work out the last point within the execution that a variable can be used by the method and will discard it when it is no longer required. This strategy isn’t always used and can be turned off, for example, by running the program in a debugger.

Static variables are also always considered GC roots. The objects they reference can be accessed at any time by the class that declared them (or the rest of the program if they are public), so .NET will always keep them around. Variables declared as ‘thread static’ will only last for as long as that thread is running.

If a managed object is passed to an unmanaged COM+ library through interop, then it will also become a GC root with a reference count. This is because COM+ doesn’t do garbage collection: It uses, instead, a reference counting system; once the COM+ library finishes with the object by setting the reference count to 0 it ceases to be a GC root and can be collected again.

If an object has a finalizer, it is not immediately removed when the garbage collector decides it is no longer ‘live’. Instead, it becomes a special kind of root until .NET has called the finalizer method. This means that these objects usually require more than one garbage collection to be removed from memory, as they will survive the first time they are found to be unused.

(emphasis mine)

What are the roots?

If you think of the objects in memory as a tree, the "roots" would be the root nodes - every object immediately accessible by your program.

Person p = new Person();
p.car = new Car(RED);
p.car.engine = new Engine();
p.car.horn = new AnnoyingHorn();

There are four objects; a person, a red car, its engine and horn. Draw the reference graph:

     Person [p]
|
Car (red)
/ \
Engine AnnoyingHorn

And you'll end up with Person at the "root" of the tree. It's live because it's referenced by a local variable, p, which the program might use at any time to refer to the Person object. This also goes for the other objects, through p.car, p.car.engine, etc.

Since Person and all other objects recursively connected to it are live, there would be trouble if the GC collected them.

Consider, however, if the following is run after a while:

p.car = new Car(BLUE);

And redraw the graph:

     Person [p]
|
Car (blue) Car (red)
/ \
Engine AnnoyingHorn

Now the Person is accessible through p and the blue car through p.car, but there is no way the red car or its parts can ever be accessed again - they are not connected to a live root. They can be safely collected.

So it's really a matter of taking every starting point (every local variable, globals, statics, everything in other threads and stack frames) — every root — and recursively following all the references to make up a list of all the "live" objects: objects which are in use and unsuitable for deletion. Everything else is garbage, waiting to be collected.

What is/are GC root objects referencing Java outer and inner classes?

Assuming that the AsyncTask has a reference to your inner class, then:

If an inner class of an Activity is running an AsyncTask, even if the Activity is finished, the GC will not be able to reclaim the Activity because the inner class has a reference to the Activity and the AsyncTask has a reference to the inner class and Android's internal thread manager has a reference to the AsyncTask. However, once the AsyncTask completes, the GC can reclaim the Activity since the internal thread manager will no longer have a reference to the AsyncTask.

This isn't really a memory leak, as it is only a temporary situation. The Activity will eventually be reclaimed. Real "memory leaks" occur when an object can never be reclaimed by the GC. Eventually such memory leaks can consume all available memory and cause a long-running application to crash with an OutOfMemoryException.

You can prevent this by cancelling your AsyncTask inside onDestroy() of the Activity.

Hopefully this answers your question.

What makes a form stay as an rooted reference?

The Application.Run method doesn't terminate until your form closes. You pass in your instance of Form1 as a parameter to Run and it becomes a local variable in a method that is currently running, and therefore a root.

Internally Application.Run actually creates an ApplicationContext which holds the reference to the form:

public class ApplicationContext : IDisposable
{
public Form MainForm
{
get { /* ... */ }
set { /* ... */ }
}

public ApplicationContext(Form mainForm)
{
this.MainForm = mainForm;
}

// ...
}

The ApplicationContext is then given to the RunMessageLoop method.

How GC finds GC roots and other object references

  1. How GC finds those roots at all?

A JVM provides an internal (C / C++) API for finding the roots. The JVM knows where the Java stack frames are, were the static frames for Java each class are, where the live JNI object handles are, and so on. (It knows because it was involved in creating them, and keeps track of them.)


  1. How GC can find local variables in the stack that are references to object and are not other type of variables.

The JVM keeps information for each method that says which cells in each stack frame are reference variables. The GC can figure out which method each stack frame corresponds to ... just like fillInStackTrace can.

(for instance constant)

That's not actually relevant. Constants (i.e. final fields) don't get special treatment.


  1. Then how GC finds fields of those objects to create an accessible tree?

The JVM keeps information for each class to say which of the static and instance fields are reference variables. There is an field in each object's header that refers to the class.

The whole process is called "marking", and it is described in the page you were looking at.


  1. Does it use instruction that are defined by jvm itself to find those objects?

I'm not sure what you are asking. But "probably yes". The GC is a component of the JVM, so everything is does is "defined by the JVM".


  1. And lastly what is the meaning of this sentence in the article?

This is not a real object virtual reference and thus is not visible

It might be saying that the thread's stack is not a Java object ... which is true. But I think you would need to ask the authors of that Ebook; see the bottom of https://www.dynatrace.com/resources/ebooks/javabook/ for their names.


You added this:

In JVM specification local variables in the frames of stack have no type and it's just somehow an array of bytes and it's the responsibility of compiler to generate type specific instruction for those local variables for instance iload, fload, aload, etc. So clearly GC can not find references to object by only looking at local variable section of the stack frames.

Actually, that is not true. As @Holder reminded me, the verifier infers the types of the cells in the stackframe by simulating the effects of the bytecodes that initialize them. In addition, each method in a classfile has a StackMapTable attribute containing information that is used to assist (and speed up) the verifier's type determination.

Later on, the GC can obtain the inferred type information from the JVM.

(In theory the GC could also make use of the StackMapTable information to determine when local variables go out of scope ... within a method. But apparently it doesn't in HotSpot JVMs; see Does the StackMapTable affect the garbage collection behavior?)


The description of garbage collection in that Ebook is (deliberately) brief and high level. But that is true of most descriptions that you will find. The deep details are complicated.

If your really want (and need) to understand how GC's work, my advice is:

  • To find out how the current Java implementations work read the OpenJDK source code.
  • Track down and read the Sun and Oracle research papers on Java GCs.
  • Get hold of a copy of a good textbook on Garbage Collection.

what is the difference between *root and **root?

struct node * is a pointer to a struct node.

struct node ** is a pointer to a pointer to a struct node.

The reason for passing in a struct node ** could be that the function needs to modify what the struct node * is actually pointing at - which seems odd for a function named calcHeight. Had it been freeNode it could have made sense. Example:

void freeNode(struct node **headp) {
free(*headp);
*headp = NULL; // make the struct node * passed in point at NULL
}

Demo

Another reason could be to make the interface consistent so that one always needs to supply a struct node ** to all functions in the functions supporting struct nodes - not only those actually needing to change what the struct node * is pointing at.


Regarding the added // EDIT part:

In this scenario there is no reason to send in a pointer-to-pointer. If you do not need to change the actual pointer, you only need to send in the value of the pointer.

Example memory layout:

Address    What's stored there
+-----+
| +0 | uint64_t ui1 = 1 <--+
+-----+ |
| +8 | uint64_t ui2 = 2 |
+-----+ |
| +16 | uint64_t* p = &ui1 ---+
+-----+

Now, if a function only need an uint64_t value, you can send in ui1, ui2 or *p to that function.

void someFunc(uint64_t val) { ++val; ... }

The changes this function makes to val are not visible to the caller of the function.

If a function is supposed to be able to make changes that are visible to the caller of the function, send in a pointer:

void someFunc(uint64_t *valp) { *valp = 10; }

Calling it with someFunc(&ui1); or someFunc(p); will change ui1 and assign 10 to it.

If you have a pointer and want to change what it's actually pointing at, which is what your original question was asking, you would need to send in a pointer to that pointer:

void someFunc(uint64_t **valpp) { *valpp = &ui2 }`

If you call that with someFunc(&p) (where p is currently pointing at ui1) you will find that after the function call, p will point at ui2:

+-----+
| +0 | uint64_t ui1 = 1
+-----+
| +8 | uint64_t ui2 = 2 <--+
+-----+ |
| +16 | uint64_t* p = &ui2 ---+
+-----+

How to get the root path references to leaked objects in .NET?

I would suggest Red gate ANTS Memory profiler and have a look at Walkthrough: Using ANTS Memory Profiler to track down a memory leak

Can aggregate root reference another root?

This is dependent on the context you are in. I will try to explain with a few different context examples and answer the question at the end.

Let's say the first context is all about adding new items to the system. In this context the Item is the aggregate root. You will most likely be constructing and adding new items to your data store or remove items. Let's say the class might look as follows:

namespace ItemManagement
{
public class Item : IAggregateRoot // For clarity
{
public int ItemId {get; private set;}

public string Description {get; private set;}

public decimal Price {get; private set;}

public Color Color {get; private set;}

public Brand Brand {get; private set;} // In this context, Brand is an entity and not a root

public void ChangeColor(Color newColor){//...}

// More logic relevant to the management of Items.
}
}

Now let's say a different part of the system allows the composition of a purchase order by adding and removing items from the order. Not only is Item not an aggregate root in this context, but ideally it will not even be the same class. Why? Because Brand, Color and all of the logic will most likely be completely irrelevant in this context. Here is some example code:

namespace Sales
{
public class PurchaseOrder : IAggregateRoot
{
public int PurchaseOrderId {get; private set;}

public IList<int> Items {get; private set;} //Item ids

public void RemoveItem(int itemIdToRemove)
{
// Remove by id
}

public void AddItem(int itemId) // Received from UI for example
{
// Add id to set
}
}
}

In this context Item is only represented by an Id. This is the only relevant part in this context. We need to know what items are on the purchase order. We don't care about brand or anything else. Now you are probably wondering how would you know the price and description of items on the purchase order? This is yet another context - view and removing items, similar to many 'checkout' systems on the web. In this context we might have the following classes:

namespace Checkout
{
public class Item : IEntity
{
public int ItemId {get; private set;}

public string Description {get; private set;}

public decimal Price {get; private set;}
}

public class PurchaseOrder : IAggregateRoot
{
public int PurchaseOrderId {get; private set;}

public IList<Item> Items {get; private set;}

public decimal TotalCost => this.Items.Sum(i => i.Price);

public void RemoveItem(int itemId)
{
// Remove item by id
}
}
}

In this context we have a very skinny version of item, because this context does not allow alteration of Items. It only allows the viewing of a purchase order and the option to remove items. The user might select an Item to view, in which case the context switches again and you may load the full item as the aggregate root in order to display all the relevant information.

In the case of determining whether you have stock, I would think that this is yet another context with a different root. For example:

namespace warehousing
{
public class Warehouse : IAggregateRoot
{
// Id, name, etc

public IDictionary<int, int> ItemStock {get; private set;} // First int is item Id, second int is stock

public bool IsInStock(int itemId)
{
// Check dictionary to see if stock is greater than zero
}
}
}

Each context, through its own version of the root and entities, exposes the information and logic it requires to perform its duties. Nothing more and nothing less.

I understand that your actual application will be significantly more complex, requiring stock checks before adding items to a PO, etc. The point is that your root should ideally already have everything loaded that is required for the function to be completed and no other context should affect the setup of the root in a different context.

So to answer your question - Any class could be either an entity or a root depending on the context and if you've managed your bounded contexts well, your roots will rarely have to reference each other. You don't HAVE to reuse the same class in all contexts. In fact, using the same class often leads to things like a User class being 3000 lines long because it has logic to manage bank accounts, addresses, profile details, friends, beneficiaries, investments, etc. None of these things belong together.

To respond to your questions

  1. Q: Why Item AR is called ItemManagement but PO AR is called just PurchaseOrder?

The namespace name reflects the name of the context you are in. So in the context of item management, the Item is the root and it is placed in the ItemManagement namespace. You can also think of ItemManagement as the Aggregate and Item as the Root of this aggregate. I'm not sure if this answers your question.


  1. Q: Should Entities (like light Item) have methods and logic as well?

That entirely depends on what you context is about. If you are going to use Item only for displaying prices and names, then no. Logic should not be exposed if it should not be used in the context. In the Checkout context example, the Item has no logic because they only serve the purpose of showing the user what the purchase order is composed of. If there is a different feature where, for example, the user can change the color of an item (like a phone) on the purchase order during checkout, you might consider adding this type of logic on the item in that context.


  1. How ARs access database? Should they have an interface.. let's say IPurchaseOrderData, with a method like void RemoveItem(int itemId)?

I apologize. I assumed that your system is using some sort of ORM like (N)Hibernate or Entity framework. In the case of such an ORM, the ORM would be smart enough to automatically convert collection updates to the correct sql when the root is persisted (given that your mapping is configured correctly).
In the case where you manage your own persistence, it's slightly more complicated. To answer the question directly - you can inject a datastore interface into the root, but I would suggest rather not.

You could have a repository that can load and save aggregates. Lets take the purchase order example with items in the CheckOut context. Your repository will likely have something like the following:

public class PurchaseOrderRepository
{
// ...
public void Save(PurchaseOrder toSave)
{
var queryBuilder = new StringBuilder();

foreach(var item in toSave.Items)
{
// Insert, update or remove the item
// Build up your db command here for example:
queryBuilder.AppendLine($"INSERT INTO [PurchaseOrder_Item] VALUES ([{toSave.PurchaseOrderId}], [{item.ItemId}])");

}
}
// ...
}

And your API or service layer would look like something this:

public void RemoveItem(int purchaseOrderId, int itemId)
{
using(var unitOfWork = this.purchaseOrderRepository.BeginUnitOfWork())
{
var purchaseOrder = this.purchaseOrderRepository.LoadById(purchaseOrderId);

purchaseOrder.RemoveItem(itemId);

this.purchaseOrderRepository.Save(purchaseOrder);

unitOfWork.Commit();
}
}

In this case your repository could become quite hard to implement. It might actually be easier to make it delete items on the purchase order and re-add the ones that are on the PurchaseOrder root (easy but not recommended).
You would have a repository per aggregate root.

Off topic:
An ORM like (N)Hibernate will deal with the Save(PO) by tracking all changes made to your root since it was loaded. So it will have an internal history of what has changed and issue the appropriate commands to bring your database state in sync with your root state when you save by emitting SQL to address each change made to the root and its children.



Related Topics



Leave a reply



Submit