I am using a tree within the left panel and a detail view (VerticalLayout with labels and buttons) within the right panel. Each node contains extensive data, that are saved by this way:
IndexedContainer nodeData;
.
.
.
tree.getContainerDataSource()
.getContainerProperty(itemId, "nodeData").setValue(nodeData)
The content for selected node is displayed in detail view. It can be modified using a modal window (clicking "Edit" button in detail view).
I am using nodeData.addValueChangeListener(detailView). The detail view implements function for updating its own content when the modal window saves nodeData. It works fine, but I have worries about memory leak. The right panel content (detailView) is destroyed when I select another node. Another view can be placed on the same place, because the nodeData of another node can have another structure. But nodeData container lives for long time and I can select it more times. My question is: Does it cause memory leak? Or the system is able to remove unaccessible object that are referenced only as a listener?
Thank you for telling me, if it can be problem. Any advices are appreciated.
I wouldn't worry about a memory leak in this case, as the listener is being injected into the component.
You can detect if there is a memory leak or not from the server, for instance, stopping Tomcat server will through some memory leak errors in the logs if there is a memory leak or any unreachable objects.
However, I would recommend overriding the detach() method on your tree to make sure you cleanup your resources once a view or a component is detached from the screen/view.
The problem is solved. It is possible to check out the component from listening changes, when it is orphaned:
if(!isAttached())
nodeData.removeValueChangeListener(this);
Related
I have a strange thing occurring; as usual, I can't post code, unfortunately, so I'm describing the problem in case anyone can suggest a possible cause.
I have an xpage with a custom control included on it; the custom control handles document locking and changing to edit/read-only modes via links. The document locking is done by setting an applicationScope variable based on the UNID. To make it more friendly for other users on the system, I run a function periodically on the page to check whether the document is locked or not and update a link/label/tooltips appropriately (e.g. if locked by another user, then the "Edit" button is disabled; when the lock is released, it's re-enabled). This is done by calling an "xagent" through a standard, simple dojo-based ajax call.
For some reason, the behavior of the system gets erratic after 45 seconds to a minute. I'm checking the lock status every ten seconds or so, so it's not happening with the first call. I'm displaying a list of records associated with the document; each record is a row in a repeat. When I first go into edit mode, the controls are all displayed as they should be, i.e. editable. If the user changes a particular value with a combobox, it updates the whole row with a partial refresh. When things get erratic, I noticed that the row starts refreshing in read-only mode, which suggests to me that the document is changing edit mode. The only time I knowingly change edit mode is if a "Cancel" or "Save" button is pressed. (The locking mechanism itself doesn't have anything to do with the edit mode.)
It certainly seems like the ajax call I'm making is at the root of this. But I've stripped the xagent and the client-side code down to practically nothing, and it's still happening. I can't see what would be causing this behavior. Can anyone hazard a guess? Thanks....
Maybe check if the server log file has warnings like:
WARNING CLFAD####W: State data not available for /page because no control tree was found in the cache.
If you're seeing those warnings, it could be that the server can no longer find the current XPage page instance in the cache. In that case the page will revert to the initial state, like when the page was first opened. That might be why the document goes to read-only mode.
The session cache of server-side page instances only holds 4 pages when xsp.persistence.mode=basic, or it holds 16 instances when xsp.persistence.mode=file or fileex.
If you load 4 xagent page instances, then that will fill the cache, and it will no longer be able to find the page instance for the current XPage you are viewing. So the XPage will stop performing server-side actions, and partial refresh will always show the initial state of that area of the page.
To avoid that problem, in the xagent page you can set viewState="nostate" on the xp:view tag, so that page instances are not saved for the xagent page, as described here:
https://tobysamples.wordpress.com/2014/12/11/no-state-no-problem/
Or else you can create and reuse one page instance for the xagent, so only one is created. That is, on the first call to the XAgent, have the xagent return the $$viewid value for the xagent page instance (#{javascript:view.getUniqueViewId()}), and then in subsequent requests to the xagent use that $$viewid in the request, to restore the existing xagent page instance instead of creating new instances that will fill the cache. So the subsequent xagent requests will be like so:
/myApp.nsf/xagent1.xsp?$$viewid=!aaaaaaaa!
It's hard to troubleshoot without code, but here are a few thoughts:
How are you checking document locking? Via a client-side JavaScript AJAX call or an XPages partial refresh? If the latter, what is the refresh area? If the former, what is the refresh area you're passing and the return HTML? Does it always occur when you're in edit mode on a row and the check happens, or independently of that? The key thing to check here is what the check for locking is doing - is it checking the server and returning a message outside the repeat, or checking the server and returning HTML that overwrites what's currently on the browser with defaults, e.g. the document mode as read mode.
What network activity is happening between the browser and the server and when? Is something else overwriting the HTML for the row, so resetting the row to read mode.
It's unlikely to be random, the key is going to be identifying the reproduceable steps to identify a common scenario/scenarios and cause.
EDIT
Following on from your additional info, is there a rendered property on the Edit link? If that calculates to false in earlier JSF lifecycle phases, the eventHandler is not available to be triggered during the Invoke Application phase. Because the eventHandler also includes the refreshId, there is no refreshId and refreshMode, so it defaults to a full refresh with no SSJS running. See this blog post for clarification http://www.intec.co.uk/view-isrenderingphase-and-buttons/.
You can view the simple testing page here
The page contains one textarea, a "create" button and a "remove" button.
When the "create" button is clicked, the "textarea" is used to create "wysihtml5".
When the "remove" button is clicked, the "wysihtml5" is removed with the code below:
$("iframe.wysihtml5-sandbox, input[name='_wysihtml5_mode']").remove();
$("body").removeClass("wysihtml5-supported");
(Please refer to this for reference.)
The problem I am having is that the memory of the elements(textarea, iframe, and links) created by wysihtml5 seem to be retained in the memory.
I take few heap snap shots with google chrome dev tool.
snap1 - when the page is initially loaded
snap2 - after the wysihtml5 is created
snap3 - after the wysihtml5 is removed
Are there memory leak? If there are, how do I prevent it from happening? (My backbone application can possibly create/destroy 100+ wysihtml5, so a clean removal of wysihtml5 is quite important!)
First of all it is not clear is the test works properly or not because nothing happens with the page when I click create button. It would be much more useful to have a repeatable test.
Nevertheless I did the test and found that the test page (working or not) have no leaks.
On the each click it allocates small amount of memory and releases it on the next click.
Sounds like the page creates the detached dom tree on the first creation and keeps it alive.
It makes sense to do warm-up create and delete actions before the first snapshot and filter everything except the objects that were allocated between first and second snapshot.
This technique was described here.
I have a question regarding coded ui UIMap.
Every time I record an action on the same application, coded ui generates a new object for the same window in the application.
It looks like:
UIAdminWindow
UIAdminWindow1
UIAdminWindow2
and so on...
every window class holds different buttons, even though it's the same window.
Thus it's very hard to keep code maintenance.
What i would like is that every time i perform actions and records on a window, even if not at the same time, the already generated class for this window, will be updated with the new controls.
any suggestions to why it happens?
Thanks a lot!
You can clean up your UIMaps by doing two things:
Use the UIMap Toolbox (from codeplex) to move controls within the UIMap so they are all under one control tree.
When you have duplicate UI controls, go to the properties for the action that references the duplicate control and change the UI Control property to point to the original control in the UIMap.
The duplicate trees should now be unreferenced and you can delete it from your map, keeping things clean.
And yes, it's a pain to do, but it's worth it for maintainability.
In UIMap.uitest you can change the action name and the control name for better maintenance.
For example: you can set UIAdminWindow as FirstAcessWindow or other name that will express comfortably the control or the action.
What I can guess is that there is some randomly generated content or element identification data such as class or title that may be causing it. This may be caused by different username for example. Also you can update the element from UI map element tree.
I have a ListView object which calls the forceLayout() method to re-render itself after its css property display is set to none. The reason i'm calling the above method is because I have a master-detail list of many listviews with only one listview visible at a time. After each list item in the master-detail list is selected the corresponding listview will be displayed.
Everytime the forceLayout() method is called, the memory increases by around 10mb and is not reclaimed even after the app is suspended. Is it a bug or am I not supposed to be calling the method frequently?
Btw, I'm running Visual Studio RC 2012 on Release Preview.
Thanks in advance.
A ton of memory leaks were fixed between Release Preview and RTM, so my first suggestion would be to grab the RTM bits and try that.
Failing that, it's probably an issue with your code holding on to references to your data or the rendered DOM elements, but without seeing your code it's hard to say what it might be.
We recently updated our Application to use JSF 2.1.3
We have an existing page that has three framesets (left nav, main, footer). Clicking on something in the main frame, causes the footer frame to be reloaded with new content. Because of this, we are losing the main frame from the logical view map after (eg. if com.sun.faces.numberOfLogicalViews is set to 10, we lose the main frame after 9 clicks). After which, trying to submit the main frame causes it to re-render, skipping the action method it's bound too.
Is there any way to keep that logical view from being removed from the map without increasing the number of logical views? I'm not sure why, but this behavior didn't occur when out app was using JSF 1.2.
We solved this problem by overriding the StateManagerImpl, and storing this particular view client side, instead of server side.
It appears in previous versions of jsf, you only needed to override the isClientSide method, but you now need to override the methods to write and restore state.